新的组件
Fragment
在Vue2中:组件必须有一个根标签
在Vue3中:组件可以没有根标签,内部会将多个标签包含在一个Fragment虚拟元素中
好处:减少标签层级,减小内存占用
Teleport
什么是Teleport? ——Teleport是一种能够将我们的组件html结构移动到指定位置的技术。
测试
App.vue
<template>
<div class='app'>
我是祖组件
<Dialog/>
</div>
</template>
<script>
import Dialog from "./components/Dialog.vue"
export default {
name: 'App',
components: {Dialog},
setup(){
}
}
</script>
<style>
.app{
background: rebeccapurple;
padding: 10px;
}
</style>
Dialog.vue
<template>
<div>
<button @click="isShow=true">点我弹个窗</button>
<!--teleport-->
<teleport to='body'>
<div class="mask" v-if="isShow">
<div class="dialog">
<h3>我是一个弹窗</h3>
<h4>一些内容</h4>
<h4>一些内容</h4>
<h4>一些内容</h4>
<button @click="isShow=false">关闭弹窗</button>
</div>
</div>
</teleport>
</div>
</template>
<script>
import Son from "./Son.vue"
import { ref} from "vue"
export default {
name: 'Dialog',
components: { Son },
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{
background: rgb(16, 138, 67);
width: 300px;
height: 300px;
position: absolute;
transform: translate(-50%,-50px);
top: 50%;
left: 50%;
text-align: center;
}
</style>
Suspense
等待异步组件时渲染一些额外内容,让应用有更好的用户体验
异步引入组件
import {defineAsyncComponent} from 'vue'
const Child = defineAsyncComponent(()=>import('./components/Child.vue'))
测试
父组件
<template>
<div class='app'>
我是App组件
<Suspense>
<template v-slot:default>
<Child/>
</template>
<!--如果有延迟测显示-->
<template v-slot:fallback>
<h3>加载中....</h3>
</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},
setup(){
}
}
</script>
<style>
.app{
background: rebeccapurple;
padding: 10px;
}
</style>
子组件
<template>
<div class='child'>
我是Child组件
{{sum}}
</div>
</template>
<script>
import {ref} from "vue"
export default {
name: 'Child',
components: { },
setup(){
let sum=ref(0)
return new Promise((resolve,rehect)=>{
setTimeout(()=>{
resolve({sum})
},3000)
})
}
}
</script>
<style>
.child{
background: blue;
padding: 10px;
}
</style>