Vue3新的组件

Mr.ZhaoAbout 2 min

1. Fragment

在 Vue2 中: 组件必须有一个根标签

在 Vue3 中: 组件可以没有根标签, 内部会将多个标签包含在一个 Fragment 虚拟元素中

好处: 减少标签层级, 减小内存占用

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>

以一个弹窗组件为示例

我们在一个嵌套的盒子里面设置弹窗

App.vue

<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.vue

<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>

我们在 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 包裹组件,并配置好 defaultfallback

      <template>
      	<div class="app">
      		<h3>我是App组件</h3>
      		<Suspense>
      			<template v-slot:default>
      				<Child/>
      			</template>
      			<template v-slot:fallback>
      				<h3>加载中.....</h3>
      			</template>
      		</Suspense>
      	</div>
      </template>
    

default:就是组件要显示的内容

fallback:就是组件没加载完全的“备胎”