1、定义:
https://cn.vuejs.org/guide/built-ins/teleport#basic-usage
<Teleport>
是一个内置组件,它可以将一个组件内部的一部分模板“传送”到该组件的 DOM 结构外层的位置去。
2、基本用法:
有时我们可能会遇到这样的场景:一个组件模板的一部分在逻辑上从属于该组件,但从整个应用视图的角度来看,它在 DOM 中应该被渲染在整个 Vue 应用外部的其他地方。
这类场景最常见的例子就是全屏的模态框。理想情况下,我们希望触发模态框的按钮和模态框本身是在同一个组件中,因为它们都与组件的开关状态有关。但这意味着该模态框将与按钮一起渲染在应用 DOM 结构里很深的地方。这会导致该模态框的 CSS 布局代码很难写。
3、简单说明:
Teleport将<Teleport to="body">...</Teleport>标签中的内容,传送到指定的位置,比如 html,body等,这里的html与body是与html中的selector是一致的。
4、事例:这里我们得用多个嵌套的SFC才可以测试出来,看下图
在TransAttrsTestC中引用了一个Teleport,TeleportTest.vue。
其它的SFC定义如下:
TeleportTest.vue
<!--
可定制插槽和 CSS 过渡效果的模态框组件。
-->
<script>
import Modal from "./Modal.vue";
export default {
components: {
Modal,
},
data() {
return {
showModal: false,
};
},
};
</script>
<template>
<div>
<button id="show-modal" @click="showModal = true">Show Modal</button>
<!-- 使用这个 modal 组件,传入 prop -->
<Teleport to="body">
<modal :show="showModal" @close="showModal = false">
<template #header>
<h3>Custom Header</h3>
</template>
</modal>
</Teleport>
</div>
</template>
<style>
.over {
z-index: 999;
width: 300px;
height: 300px;
position: relative;
background-color: antiquewhite;
}
</style>
<script>
export default {
props: {
show: Boolean
}
}
</script>
<template>
<Transition name="modal">
<div v-if="show" class="modal-mask">
<div class="modal-container">
<div class="modal-header">
<slot name="header">default header</slot>
</div>
<div class="modal-body">
<slot name="body">default body</slot>
</div>
<div class="modal-footer">
<slot name="footer">
default footer
<button
class="modal-default-button"
@click="$emit('close')"
>OK</button>
</slot>
</div>
</div>
</div>
</Transition>
</template>
<style>
.modal-mask {
position: fixed;
z-index: 8;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.5);
display: flex;
transition: opacity 0.3s ease;
}
.modal-container {
width: 300px;
margin: auto;
padding: 20px 30px;
background-color: #fff;
border-radius: 2px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.33);
transition: all 0.3s ease;
}
.modal-header h3 {
margin-top: 0;
color: #42b983;
}
.modal-body {
margin: 20px 0;
}
.modal-default-button {
float: right;
}
/*
* 对于 transition="modal" 的元素来说
* 当通过 Vue.js 切换它们的可见性时
* 以下样式会被自动应用。
*
* 你可以简单地通过编辑这些样式
* 来体验该模态框的过渡效果。
*/
.modal-enter-from {
opacity: 0;
}
.modal-leave-to {
opacity: 0;
}
.modal-enter-from .modal-container,
.modal-leave-to .modal-container {
-webkit-transform: scale(1.1);
transform: scale(1.1);
}
</style>
Modal.vue
这个事例中的二个文件SFC定义来自官方:https://cn.vuejs.org/examples/#modal
5、运行结果:
说明:
1)去掉Teleport与不去掉Teleport,运行的效果是一样的。
2)加上Teleport,那么这个部分的modal将会被加到<body></body>之间
3)去掉Teleport,那么modal会显示在这个SFC里面。
6、我们来看下二者的不同的地方:
有Teleport的时候,会在<body>...</body>之间加入,一般会在</body>之前。
没有Teleport的时候,会在TransAttrsTestC中加入。
7、总结:
这个例子,运行的效果虽然是一样的,但是在【元素】显示的位置是不一样的,Teleport会将TransAttrsTestC中的modal直接加入到body中。
如果没有Teleport的话,那么在那里定义,就属于那一个SFC。