前言
对比 Vue2 ,引出并展开 Vue3 。
本文讲述了 Teleport 传送门是什么,以及使用方法和代码示例。
介绍
学过 React 的同学可能知道, Portal 也提供了一种将子节点渲染到存在于父组件以外的 DOM 节点的优秀方案,当然咱们大名鼎鼎的 Vue3 也做到了,关于这方面的功能需求,第三方库也是有很多的,这里就不详谈了,感兴趣的可以自己去了解。
Teleport 传送门是 Vue3 内置的组件,它是一种能够将我们的模板移动到 DOM 中 Vue app 之外其他位置的技术。
Vue2 示例
先拿 Vue2 举例,上来讲概念直接上 Vue3 代码有些朋友肯定不太懂。
我们市场上很多项目,大部分都包含弹框,提示用户一些信息,比如 ElementUI 的弹框组件。
这样的弹框,我们在开发的时候都会选择创建一个组件,将来有页面需要用的时候,直接引入,再传入相应的配置即可。
咱们先来看一下 Vue2
中如何实现弹框。
在 components
目录下,新建 modal.vue
,这个文件咱们用作弹框组件。
<template>
<div>
<button @click="flag = true">打开弹框</button>
<div v-if="flag" class="modal">
<div>
<h1>Hello</h1>
<button @click="flag = false">
关闭
</button>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
flag: false
}
}
}
</script>
<style>
.modal {
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
background-color: rgba(0,0,0,.5);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.modal div {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: white;
width: 600px;
height: 300px;
padding: 5px;
border-radius: 15px;
}
</style>
然后引入该组件:
<template>
<div>
<Modal />
</div>
</template>
<script>
import Modal from './components/modal.vue'
export default {
components: { Modal },
}
</script>
然后咱们打开控制台,看一下 DOM
结构,可以发现咱们的页面内容全部被套在 #app
这个元素下,而我们的弹框组件则是被套在父组件的中,也就是说哪个页面引用了弹框组件,弹框组件就被嵌套在此。
div
中渲染的,那么问题来了,此时处理嵌套组件的定位与 z-index
样式都会变得很困难,也就是由于你弹框组件受父组件影响,所以你在写样式的时候都需要考虑到父组件,比如 z-index
不能太高,定位不能使用绝对定位等,非常恶心。
Vue3 示例
那么有没有一种办法,既能享受到
Vue
带来的功能,又不受父组件影响呢?答案是有,有请我们的主角登场,废话不多说,马上用Vue3
重构一把。
首先打开项目根目录下 index.html
文件,在 <div id="app"></div>
下加入一段代码:
为什么要加入这一行呢,一会你就知道了。
加完之后呢,我们打开刚才用 Vue2
编写的弹框组件,咱们做一些修改:
<template>
<button @click="flag = true">打开弹框</button>
<!-- 注意这里,把刚才在 index.html 加入的节点,放到这里 ↓↓↓ -->
<!-- 然后被teleport包裹的内容,就会传送到#modal节点上(也就是成功跑到了#app节点之外) -->
<!-- 虽然跑到了#app节点之外,但依然可以享有vue带来的功能 -->
<teleport to="#modal">
<div v-if="flag" class="modal">
<div>
<h1>Hello</h1>
<button @click="flag = false">
关闭
</button>
</div>
</div>
</teleport>
</template>
<script>
export default {
data() {
return {
flag: false
}
}
}
</script>
<style>
.modal {
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
background-color: rgba(0,0,0,.5);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
.modal div {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: white;
width: 600px;
height: 300px;
padding: 5px;
border-radius: 15px;
}
</style>
再比如,我们直接把弹框传送到 body
节点上,直接改 to="body"
属性即可。
非常的简单,省时省力。
写在后面
这些示例代码都是可以运行的,如果你还是不懂,可以自己亲自复制代码跑起来。
参考
https://juejin.cn/post/7195391026956075069
标签:Teleport,center,flex,传送门,弹框,modal,Vue3,组件 From: https://www.cnblogs.com/miangao/p/17856087.html