← 返回首页
Vue3基础教程(三十八)
发表时间:2021-08-15 17:49:30
Fragment和Teleport

1.Fragment 在Vue 3中,我们可以期待的另一个令人兴奋的补充是Fragment。 你可能会问,什么是碎片?如果你创建一个Vue组件,那么它只能有一个根节点。 这意味着不能创建这样的组件:

<template>
  <div>Hello</div>
  <div>World</div>
</template>

原因是代表任何Vue组件的Vue实例需要绑定到一个单一的DOM元素中。唯一可以创建一个具有多个DOM节点的组件的方法就是创建一个没有底层Vue实例的功能组件。 结果发现React社区也遇到了同样的问题。他们想出的解决方案是一个名为 Fragment 的虚拟元素。Fragment看起来像一个普通的DOM元素,但它是虚拟的,根本不会在DOM树中呈现。这样我们可以将组件功能绑定到一个单一的元素中,而不需要创建一个多余的DOM节点。 目前你可以在Vue 2中使用vue-fragments库来使用Fragments,而在Vue 3中,你将会在开箱即用!

2.Teleport

Teleport 提供了一种干净的方法,允许我们控制在 DOM 中哪个父节点下呈现 HTML,而不必求助于全局状态或将其拆分为两个组件。

实例: 以模态框举例,可以在一个深度嵌套的 UI 组件中定义一个模态框,通过 Teleport To 把该模态框 append 到 body 的标签下。

ModalButton.vue

<template>
    <button @click="modalOpen = true">
        Open full screen modal! (With teleport!)
    </button>

    <teleport to="body">
        <div v-if="modalOpen" class="modal">
            <div>
                I'm a teleported modal!
                (My parent is "body")
                <button @click="modalOpen = false">
                    Close
                </button>
            </div>
        </div>
    </teleport>
</template>

<script>
    import { ref } from 'vue'
    export default {
        name: 'modal-button',
        setup () {
            const modalOpen = ref(false)
            return {
                modalOpen
            }
        }
    }
</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: 300px;
        height: 300px;
        padding: 5px;
    }
</style>

App.vue

<template>
    <h2>Teleport演示案例</h2>
    <modal-button></modal-button>
</template>

<script lang="ts">
    import {
        defineComponent,
    } from 'vue'
    import ModalButton from '@/components/ModalButton.vue'
    export default {
        name: 'App',
        components: {
            ModalButton
        },
        setup() {
            return {}
        }
    }

</script>
<style>
    #app {
        height: 100%;
        margin: 0;
        padding: 0;
        border: 0;
    }
    /*解决微信浏览器背景默认灰色问题*/
    body, html {
        background: #ffffff
    }
</style>