1. Fragment
- 在Vue2中: 组件必须有一个根标签
- 在Vue3中: 组件可以没有根标签, 内部会将多个标签包含在一个
Fragment
虚拟元素中 - 好处: 减少标签层级, 减小内存占用
咱就是说,vue越来越react化了。。。。。
2. Teleport
- 什么是
Teleport
?——Teleport
是一种能够将我们的组件html结构移动到指定位置的技术。 -
<teleport to="移动位置"> <div v-if="isShow" class="mask"> <div class="dialog"> <h3>我是一个弹窗</h3> <button @click="isShow = false">关闭弹窗</button> </div> </div> </teleport>
以一个弹窗组件为示例来看看:
我们来个嵌套的盒子,然后在最里面的盒子设置弹窗
父组件:
<template>
<div class="app">
<h3>我是App组件</h3>
<Child />
</div>
</template>
<script>
import Child from "./components/Child";
export default {
name: "App",
components: { Child },
};
</script>
<style>
.app {
background-color: gray;
padding: 10px;
}
</style>
子组件Child:
<template>
<div class="child">
<h3>我是Child组件</h3>
<Son />
</div>
</template>
<script>
import Son from "./Son";
export default {
name: "Child",
components: { Son },
};
</script>
<style>
.child {
background-color: skyblue;
padding: 10px;
}
</style>
孙子组件Son:
<template>
<div class="son">
<h3>我是Son组件</h3>
<Dialog />
</div>
</template>
<script>
import Dialog from "./Dialog.vue";
export default {
name: "Son",
components: { Dialog },
};
</script>
<style>
.son {
position: relative;
background-color: orange;
padding: 10px;
}
</style>
弹窗组件dialog:
<template>
<div>
<button @click="isShow = true">点我弹个窗</button>
<div v-if="isShow" class="mask">
<div class="dialog">
<h3>我是一个弹窗</h3>
<h4>一些内容</h4>
<h4>一些内容</h4>
<h4>一些内容</h4>
<button @click="isShow = false">关闭弹窗</button>
</div>
</div>
</div>
</template>
<script>
import { ref } from "vue";
export default {
name: "Dialog",
setup() {
let isShow = ref(false);
return { isShow };
},
};
</script>
<style>
.mask {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background-color: rgba(0, 0, 0, 0.5);
}
.dialog {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
text-align: center;
width: 300px;
height: 300px;
background-color: green;
}
</style>
给最里面的盒子加了定位,因为相对定位会找他外层最近的定位盒子进行定位,所以效果就是这样了,我们希望这个弹窗是在body下呈现的
我们在Dialog组件中加一个teleport
标签
<template>
<div>
<button @click="isShow = true">点我弹个窗</button>
<teleport to="body">
<div v-if="isShow" class="mask">
<div class="dialog">
<h3>我是一个弹窗</h3>
<h4>一些内容</h4>
<h4>一些内容</h4>
<h4>一些内容</h4>
<button @click="isShow = false">关闭弹窗</button>
</div>
</div>
</teleport>
</div>
</template>
效果就是这样的:
3. Suspense
-
等待异步组件时渲染一些额外内容,让应用有更好的用户体验
用法:
- 异步引入组件
import {defineAsyncComponent} from 'vue'
const Child = defineAsyncComponent(()=>import('./components/Child.vue'))
- 使用
Suspense
包裹组件,并配置好default
与fallback
default:就是组件要显示的内容
fallback:就是组件没加载完全的“备胎”(类似于img标签的alt属性)
<template>
<div class="app">
<h3>我是App组件</h3>
<Suspense>
<template v-slot:default>
<Child/>
</template>
<template v-slot:fallback>
<h3>加载中.....</h3>
</template>
</Suspense>
</div>
</template>