Fragment
在Vue2中,template标签内,必须有一个div标签,作为根标签。
在Vue3中,可以没有div根标签,如果没有的话,Vue3会将多个标签包装在一个Fragment
虚拟元素里。
这么做的目的:减少标签的层级,减少内存占用。
Teleport
<Teleport>
是一个内置组件,可以将一个组件内部的模板传送到该组件DOM外部的位置去。
App.vue
<template>
<div class="outer">
<h3>Tooltips with Vue 3 Teleport</h3>
<div>
<MyModal/>
</div>
</div>
</template>
<script>
import MyModal from "./components/MyModal.vue";
export default {
name: 'App',
components: {MyModal},
setup() {
}
}
</script>
MyModal.vue
<template>
<button @click="open = true">Open Modal</button>
<Teleport to="body"><!--我希望将Teleport包裹的内容,插入到body里面-->
<div v-if="open" class="modal">
<p>Hello from the modal!</p>
<button @click="open = false">Close</button>
</div>
</Teleport>
</template>
<script>
import {ref} from 'vue'
export default {
name: 'MyModal',
setup() {
const open = ref(false);
return {
open
}
}
}
</script>
<style scoped>
.modal {
position: fixed;
z-index: 999;
top: 20%;
left: 50%;
width: 300px;
margin-left: -150px;
border: 1px solid red;
}
</style>
Suspense
<Suspense>
是一个内置组件,用来在组件树中协调对异步依赖的处理。它让我们可以在组件树上层等待下层的多个嵌套异步依赖项解析完成,并可以在等待时渲染一个加载状态,需要结合异步依赖,才能看到效果。
为了演示效果,将网络调整为Fast 3G,来查看效果。
Child.vue
<template>
<div id="Child">
<h1>我是子组件</h1>
</div>
</template>
<script>
export default {
name: "Child"
}
</script>
<style scoped>
#Child {
background-color: green;
padding: 10px;
}
</style>
App.vue
<template>
<div id="App">
<h1>我是父组件</h1>
<Suspense>
<template v-slot:default><!--正常加载的时候,展示Child组件-->
<Child/>
</template>
<template v-slot:fallback><!--网速慢,或者加载失败的时候,提示加载中……-->
<h1>加载中……</h1>
</template>
</Suspense>
</div>
</template>
<script>
// import Child from "./components/Child.vue";// 静态引入
import {defineAsyncComponent} from "vue";
const Child = defineAsyncComponent(() => import("./components/Child.vue"));// 异步引入
export default {
name: 'App',
components: {Child}
}
</script>
<style scoped>
#App {
background-color: red;
padding: 10px;
}
</style>