Teleport
Vue 3.0新特性之一。
Teleport
是一种能够将我们的模板渲染至指定DOM
节点,不受父级style
、v-show
等属性影响,但data
、prop
数据依旧能够共用的技术;类似于 React
的 Portal
。
主要解决的问题 因为Teleport
节点挂载在其他指定的DOM
节点下,完全不受父级style
样式影响
使用方法
通过to 属性 插入指定元素位置 to="body" 便可以将Teleport
内容传送到指定位置
<Teleport to="body">
<Loading></Loading>
</Teleport>
也可以自定义传送位置 支持 class id等 选择器
<div id="app"></div>
<div class="modal"></div>
<template>
<div class="dialog">
<header class="header">
<div>我是弹框</div>
<el-icon>
<CloseBold />
</el-icon>
</header>
<main class="main">
我是内容12321321321
</main>
<footer class="footer">
<el-button size="small">取消</el-button>
<el-button size="small" type="primary">确定</el-button>
</footer>
</div>
</template>
<script setup lang='ts'>
import { ref, reactive } from 'vue'
</script>
<style lang="less" scoped>
.dialog {
width: 400px;
height: 400px;
background: #141414;
display: flex;
flex-direction: column;
position: absolute;
left: 50%;
top: 50%;
margin-left: -200px;
margin-top: -200px;
.header {
display: flex;
color: #CFD3DC;
border-bottom: 1px solid #636466;
padding: 10px;
justify-content: space-between;
}
.main {
flex: 1;
color: #CFD3DC;
padding: 10px;
}
.footer {
border-top: 1px solid #636466;
padding: 10px;
display: flex;
justify-content: flex-end;
}
}
</style>
多个使用场景
<Teleport to=".modal1">
<Loading></Loading>
</Teleport>
<Teleport to=".modal2">
<Loading></Loading>
</Teleport>
动态控制teleport
使用disabled 设置为 true则 to属性不生效 false 则生效
<teleport :disabled="true" to='body'>
<A></A>
</teleport>
源码解析
在创建teleport 组件的时候会经过patch 方法 然后调用teleport 的process 方法
主要是创建 更新 和删除的逻辑
他通过 resolveTarget 函数 获取了props.to 和 querySelect 获取 了目标元素
然后判断是否有disabled 如果有则 to 属性不生效 否则 挂载新的位置
新节点disabled 为 true 旧节点disabled false 就把子节点移动回容器
如果新节点disabled 为 false 旧节点为true 就把子节点移动到目标元素
遍历teleport 子节点进行unmount方法去移除