Teleport组件介绍
Vue3新增组件,该组件可以将制定内容渲染到制定容器中。默认内容都是渲染到元素app内,我们可以将其渲染到任意节点 (传送门)
const shapeFlag = isString(type)
? ShapeFlags.ELEMENT: isTeleport(type) // 如果是穿梭框
? ShapeFlags.TELEPORT: isObject(type)
? ShapeFlags.STATEFUL_COMPONENT :isFunction(type)
? ShapeFlags.FUNCTIONAL_COMPONENT:0; // 函数式组件
1
2
3
4
5
2
3
4
5
创建虚拟节点的时候标识组件类型。
组件挂载
if(shapeFlag & ShapeFlags.TELEPORT){
type.process(n1,n2,container,anchor,{
mountChildren, // 挂载孩子
patchChildren, // 更新孩子
move(vnode,container){ // 移动元素
hostInsert(vnode.component? vnode.component.subTree.el : vnode.el,container)
}
})
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
export const TeleportImpl = {
__isTeleport:true,
process(n1,n2,container,anchor,internals){
let {mountChildren,patchChildren,move} = internals
if(!n1){
// 创建一个目标
const target = (n2.target = document.querySelector(n2.props.to));
if(target){
mountChildren(n2.children,target,anchor)
}
}else{
patchChildren(n1,n2,container); // 比对儿子
if(n2.props.to !== n1.props.to){ // 更新并且移动位置
// 获取下一个元素
const nextTarget = document.querySelector(n2.props.to);
n2.children.forEach(child =>move(child,nextTarget));
}
}
}
}
export const isTeleport = (type) => type.__isTeleport
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21