Vue3的新组件Fragment、Fragment、Suspense

文章目录

  • Fragment
  • Teleport
  • Suspense
    • 异步组件引入
      • 静态引入
      • 动态引入(异步引入)
    • Suspense
      • setup返回Promise对象

Fragment

  • 在Vue2中:组件必须有一个根标签
  • 在Vue3中:组件可以没有根标签,但内部会将多个标签包含在一个Fragment虚拟元素中,该元素不会解析到页面上。
    好处:减少标签层级,减小内存占用

Teleport

Teleport是一种能够将我们的组件html结构移动到指定位置的技术。
eg:将弹窗移动到body中。
弹窗原本是嵌套在多级子组件中:
Vue3的新组件Fragment、Fragment、Suspense_第1张图片
如果使用Teleport标签包裹,利用to属性可以跳转到任意位置
eg:跳转到body中:

<template>
    <div>
        <button @click="isShow=true">点我弹个窗button>
        <teleport to="body">
        <div v-if="isShow" class="mask">
        <div v-if="isShow" class="dialog">
            <h3>我是一个弹窗h3>
            <button @click="isShow=false">关闭弹窗button>
        div>
        div>
        teleport>
    div>
template>

<script>
import {ref} from "vue"
export default {
    name: 'DialogVue',
    setup() {
        let isShow = ref(false)
        return{isShow}
    }
}
script>

<style>

.dialog{
    text-align: center;
    width: 300px;
    height: 150px;
    background-color:rgb(11, 59, 11);

    position:absolute;
    top:50%;
    left:50%;
    transform: translate(-50%,-50%);
}
.mask{
    position: absolute;
    top:0;
    bottom:0;
    left:0;
    right:0;
    background-color:rgba(0,0,0,0.5) ;
}

style>

效果:
Vue3的新组件Fragment、Fragment、Suspense_第2张图片
Vue3的新组件Fragment、Fragment、Suspense_第3张图片

Suspense

异步组件引入

静态引入

我们之前都是使用 import Child from './components/Child'这种方式引入组件的,这种方式叫做静态引入
静态引入的特点是只要引入的组件没出来页面就不进行显示。
eg:App组件中嵌套着Child子组件,使用静态引入的方式的话,如果child组件没有加载进来,app组件是不会显示在页面上的,所以App组件最终会和Child组件一同渲染到页面上

动态引入(异步引入)

// defineAsyncComponent定义一个异步组件
import { defineAsyncComponent } from 'vue'
const Child = defineAsyncComponent(()=>import('./components/Child'))//动态引入(异步引入)

上述引入方法就是异步引入。
特点是哪个组件先加载好就先显示哪个组件。
eg:App组件中嵌套着Child子组件,使用异步引入的方式的话,如果child组件没有加载进来,app组件已经加载好了,那app组件就会先显示在页面上,Child组件什么时候加载完什么时候在进行显示。

所以异步引入组件可能会出现页面抖动的现象,为了解决这个现象引入Suspense

Suspense

Suspense是一个标签,他底部的实现原理是使用插槽实现的。
使用格式:

    <Suspense>
      <template v-slot:default>
        <组件名 />
      template>
      <template v-slot:fallback>
        <h3>如果组件加载不出来显示的内容h3>
      template>
    Suspense>

使用:
eg:
App.vue:

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

<script>
// import Child from './components/Child'//静态引入
// defineAsyncComponent定义一个异步组件
import { defineAsyncComponent } from 'vue'
const Child = defineAsyncComponent(()=>import('./components/Child'))//动态引入(异步引入)
export default { 
  name: 'AppVue',
  components: { Child },
}
script>

<style>
.app {
  background: #333;
  padding: 10px;
}
style>

Vue3的新组件Fragment、Fragment、Suspense_第4张图片

setup返回Promise对象

如果使用了Suspense和异步组件,那么setup也可以返回Promise对象了。
Child.vue:

<template>
    <div class="child">
        <h2>我是child组件h2>
        {{sum}}
    div>
template>

<script>
import { ref } from '@vue/reactivity'
export default {
    name: 'ChildVue',
    setup() {
        let sum = ref(0)
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve({sum})
            },1000)
        })
    }
}
script>
<style>

.child {
    background: rgb(225, 205, 148);
    padding: 10px;
}
style>

App.vue:

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

<script>
// import Child from './components/Child'//静态引入
// defineAsyncComponent定义一个异步组件
import { defineAsyncComponent } from 'vue'
const Child = defineAsyncComponent(()=>import('./components/Child'))//动态引入(异步引入)
export default { 
  name: 'AppVue',
  components: { Child },
}
script>

<style>
.app {
  background: #333;
  padding: 10px;
}
style>

Vue3的新组件Fragment、Fragment、Suspense_第5张图片
那么setup也可以使用async修饰了,因为await的返回值就是Promise
child.vue

<template>
    <div class="child">
        <h2>我是child组件h2>
        {{sum}}
    div>
template>

<script>
import { ref } from '@vue/reactivity'
export default {
    name: 'ChildVue',
    async setup() {
        let sum = ref(0)
       const p = new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve({sum})
            },1000)
       })
        return await p;
    }
}
script>
<style>

.child {
    background: rgb(225, 205, 148);
    padding: 10px;
}
style>

你可能感兴趣的:(vue2+vue3,前端,javascript,vue.js)