这篇文章主要介绍“Vue中如何使用Teleport组件”,在日常操作中,相信很多人在Vue中如何使用Teleport组件问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Vue中如何使用Teleport组件”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!
01-组件套组件层次结构很深时
比如:现在有两个组件,父组件,子组件,在后代组件内,添加一个按钮,弹出一个模态框,让它在页面垂直水平居中显示
如下所示,父组件如下所示
App.vue
<template>
<div class="App">
我是父组件
<Child />
</div>
</template>
<script setup>
import Child from "./Child.vue"
</script>
<style>
.App {
width: 400px;
height: 400px;
background:red;
}
</style>如下是
Child组件,示例代码如下所示
Child.vue,我们需要在孙(后代)组件,添加一个按钮,点击按钮,弹出一个弹框,水平垂直居中显示在页面中央
<template>
<div class="child">
<p>我是子组件</p>
<button @click="isModel=true">打开模态框</button>
<div class="mask-dialog" v-if="isModel">
<div class="box">
<h3>我是标题</h3>
<div>我是弹框内容</div>
<div>
<button @click="isModel=false">关闭</button>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref } from "vue";
let isModel = ref(false);
</script>
<style>
.child {
width: 300px;
height:300px;
background:green;
}
/**灰色遮罩层 */
.mask-dialog {
width: 100%;
height:100%;
position:absolute;
left:0;
top:0;
background:rgba(0,0,0,0.5)
}
.box {
width: 200px;
height:200px;
position:absolute;
left:50%;
top:50%;
transform:translate(-50%,-50%);
background:pink;
text-align:center;
}
</style>上面的子组件中有一个
button按钮来触发打开当前组件的模态框,里面存在着控制弹框的显示和隐藏的逻辑,当嵌套的组件比较深,复杂时
如果父级元素存在定位,那在控制子元素的位置时,用
css的
transform或者
position:absolute,参照对象的变更,会破坏布局结构,会出现一些
css样式
控制的问题,解决起来会非常的痛苦
那这个
Teleport组件就是为了解决这类问题,可以将指定的
DOM结构片段,独立于到组件外面去,不受当前组件布局结构的影响
经过
Teleport的修改后
<template>
<div class="child">
<p>我是子组件</p>
<button @click="isModel=true">打开模态框</button>
<Teleport to="body">
<div class="mask-dialog" v-if="isModel">
<div class="box">
<h3>我是标题1</h3>
<div>我是弹框内容</div>
<div>
<button @click="isModel=false">关闭</button>
</div>
</div>
</div>
</Teleport>
</div>
</template>
<script setup>
import { ref } from "vue";
let isModel = ref(false);
</script>
<style>
.child {
width: 300px;
height:300px;
background:green;
}
/**灰色遮罩层 */
.mask-dialog {
width: 100%;
height:100%;
position:absolute;
left:0;
top:0;
background:rgba(0,0,0,0.5)
}
.box {
width: 200px;
height:200px;
position:absolute;
left:50%;
top:50%;
transform:translate(-50%,-50%);
background:pink;
text-align:center;
}
</style><Teleport>接收一个
to prop来指定传送的目标。
to的值可以是一个
CSS选择器字符串,或
id,也可以是一个
DOM元素对象。这段代码的作用就是告诉
Vue把以下模板片段传送到
body标签下
<Teleport to="#some-id">html结构代码</Teleport> <Teleport to=".some-class">html结构代码</Teleport> <Teleport to="body">html结构代码</Teleport> <Teleport to="html">html结构代码</Teleport>
02-Teleport组件
它是
Vue官方提供的一个内置组件,它可以将一个组件内部的一部分模板“传送”到该组件的
DOM结构外层的位置去 也就是一种能够将我们的组件
html结构移动到指定位置的技术
<teleport to="移动到指定的位置,可以是html,body,或id,class"> 里面是Html结构模板内容 </teleport>
注意
<Teleport>挂载时,传送的
to目标必须已经存在于
DOM中。理想情况下,这应该是整个
Vue应用
DOM树外部的一个元素。如果目标元素也是由
Vue渲染的,你需要确保在挂载
<Teleport>之前先挂载该元素
这个
teleport将指定的模板
html,放置到页面当中指定的位置处,它是有条件的,不是可以任意传送的
在安装组件之前,目标元素必须存在,即,目标不能由组件本身呈现,理想情况下应该位于整个
Vue组件树之外。
如下代码是不行的
<template>
<div>
<Teleport to=".content">
<div>我是头部的内容</div>
</Teleport>
</div>
<div>
底部内容
<div></div>
</div>
</template>
<script setup>
</script>
<style>
h2 {
color: red;
}
</style>03-需要知道的
teleport只是改变了渲染的
DOM结构,它不会影响组件间的逻辑关系。也就是说,如果
<Teleport>包含了一个组件,那么该组件始终和这个使用了
<teleport>的组件保持逻辑上的父子关系。传入的
props和触发的事件也会照常工作。
这也意味着来自父组件的注入也会按预期工作,子组件将在
Vue Devtools中嵌套在父级组件下面,而不是放在实际内容移动到的地方
位置移动了,提现在结构模板上,但是数据逻辑依旧存在关联的
04-如何禁用 Teleport
在某些场景下可能需要视情况禁用
<Teleport>。举例来说,我们想要在桌面端将一个组件当做浮层来渲染,但在移动端则当作行内组件。我们可以通过对
<Teleport>动态地传入一个
disabled prop来处理这两种不同情况
<Teleport :disabled="isMobile"> ... </Teleport>
这里的
isMobile状态可以根据
CSS media query的不同结果动态地更新
05-多个 Teleport 共享目标时
一个可重用的模态框组件可能同时存在多个实例。对于此类场景,多个
<Teleport>组件可以将其内容挂载在同一个目标元素上,而顺序就是简单的顺次追加,后挂载的将排在目标元素下更后面的位置上
比如下面这样的用例
<Teleport to=".content"> <div>A</div> </Teleport> <Teleport to=".content"> <div>B</div> </Teleport>
渲染的结果为
<div class="content"> <div>A</div> <div>B</div> </div>