【Vue3】16-Teleport

42 阅读1分钟

1. 作用与场景(参考 vue3-Teleport

一个组件模板的一部分在逻辑上从属于该组件,但从整个应用视图的角度来看,它在 DOM 中应该被渲染在整个 Vue 应用外部的其他地方。这类场景最常见的例子就是全屏的模态框。

<Teleport> 只改变了渲染的 DOM 结构,它不会影响组件间的逻辑关系。也就是说,如果 <Teleport> 包含了一个组件,那么该组件始终和这个使用了 <Teleport> 的组件保持逻辑上的父子关系。传入的 props 和触发的事件也会照常工作。

这也意味着来自父组件的注入也会按预期工作,子组件将在 Vue Devtools 中嵌套在父级组件下面,而不是放在实际内容移动到的地方。

2. 用法

模态框组件

<template>
<div class="dialog">
    <div class="info">确定删除吗?</div>
    <div class="btn">
        <button @click="confirm" class="confirm">确定</button>
        <button class="cancel">取消</button>
    </div>
</div>
</template>

<script setup lang="ts">
const emit = defineEmits(['on-confirm'])

const confirm = () => {
    emit('on-confirm')
}
</script>

<style scoped>
.dialog {
    width: 300px;
    height: 300px;
    border: 1px solid #fff;
    border-radius: 5px;
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    background-color: rgb(255, 241, 47);
}
.info {
    color: red;
    text-align: center;
    font-size: 20px;
    height: 200px;
    line-height: 200px;
}
.btn {
    display: flex;
}
.btn button {
    display: block;
    margin: auto;
    width: 80px;
    height: 30px;
    border: 1px solid #ccc;
    cursor: pointer;
    border-radius: 3px;
}
.confirm {
    background-color: #ddd;
}
.cancel {
    background-color: rgb(252, 58, 58);
    color: #fff;
}
</style>

父组件

<template>
    <div class="frame">
        <!-- disabled:决定是否开启传送门;to:决定传送到哪里,值为 CSS 选择器 -->
        <!-- 根据 disabled 的值,决定是否将 Dialog 传送到 body 标签中 -->
        <Teleport :disabled="disable" to='body'>
            <Dialog @on-confirm="confirm"></Dialog>
        </Teleport>
    </div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import Dialog from './components/Dialog.vue';
let disable = ref(true)
const confirm = () => {
    disable.value = !disable.value
    console.log(disable.value)
}
</script>

<style scoped>
.frame {
    position: relative;
    background-color: skyblue;
    height: 50vh;
}
</style>

呈现的效果就是:点击 “确定” 按钮可以切换模态框的位置

image.png

image.png