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>