Dom传送门
# 题目:
看到这个题大致的意思是 vue 有提供一个内置组件,用于将插槽内容渲染到另外的一个 Dom 元素中,变成改 Dom 元素的一部分。那么到底是什么意思呢?让我们看看吧。
# 分析:
让我们来看到 vue 官方文档对 teleport 的介绍吧。一个内置组件,可以将组件内部的一部分模板,传送到该组件 Dom 结构的外层去。并且还举了一个模态框的例子。其实我们可以简单去理解,它就像一个哆啦 A 梦的任意门,能够将东西瞬移到其他地方。举个例子:例如在子组件 header 中我们用到 dialog 组件的时候,此时 dialog 就会被渲染到一层层子组件的内部,z-index 设置很困难。但从用户感知的角度来说,dialog 应该是一个独立的组件。从 Dom 结构应该完全剥离 Vue 顶层挂载的组件 Dom。简单来讲就是我既希望在组件内部用 dialog,但是又不希望渲染在嵌套的组件 Dom 中。
# 举例:
Teleport 的使用: 我们希望 Dialog 渲染的 dom 和顶层组件是兄弟节点关系, 在 index.html 文件中定义一个供挂载的元素
<body>
<div id="app"></div>
<div id="dialog"></div>
</body>
定义一个 Dialog 组件 Dialog.vue, 留意 to 属性, 与上面的 id 选择器一致
<template>
<teleport to="#dialog">
<div class="dialog">
<div class="dialog_wrapper">
<div class="dialog_header" v-if="title">
<slot name="header">
<span>{{ title }}</span>
</slot>
</div>
</div>
<div class="dialog_content">
<slot></slot>
</div>
<div class="dialog_footer">
<slot name="footer"></slot>
</div>
</div>
</teleport>
</template>
最后在一个子组件 Header.vue 中使用 Dialog 组件, 这里主要演示 Teleport 的使用。
<div class="header">
...
<navbar />
<Dialog v-if="dialogVisible"></Dialog>
</div>
...
渲染效果如下:
# 解决:
所以这里我们要解决这个问题的话,直接用 teleport 将 span 渲染到 body 即可。
<script setup>
const msg = "Hello World";
</script>
<template>
<!-- 使用 teleport 将内容渲染到 body 的子元素中 -->
<teleport to="body">
<span>{{ msg }}</span>
</teleport>
</template>