【vue3入门】-【22】 动态组件&组件保持存活&异步组件

动态组件

有些场景下会需要在两个组件之间来回切换,比如tab页面

App.vue

<template>

  <!--组件标签-->
  <component :is="tabComponent"></component>
  <button @click="changeHandle">切换组件</button>
</template>
<script>
import ComponentA from "./components/ComponentA.vue";
import ComponentB from "./components/ComponentB.vue";
export default {
  data() {
    return {
      tabComponent:"ComponentB" // 不是字符串时console会有告警
    }
  },
  components:{
    ComponentA,
    ComponentB
  },
  methods:{
    changeHandle(){

      // 如果后面的this.tabComponent的值等于ComponentA,则将ComponentB赋给前面的this.tabComponent
      // === 是严格相等,包括类型和值, == 是非严格的相等,通常用在不同类型的值对比
      // this.tabComponent = this.tabComponent=="ComponentA" ?"ComponentB":"ComponentA"
      // 上面的表达式等价于:
      if(this.tabComponent=="ComponentA"){
        this.tabComponent="ComponentB"
      }else{
        this.tabComponent="ComponentA"
      }
    }
  }
}
</script>

ComponentA.vue

<template>
    <h3>ComponentA</h3>
</template>

ComponentB.vue

<template>
    <h3>ComponentB</h3>
</template>

组件保持存活

当使用<component :is="...">来在多个组件间切换时,被切换掉的组件会被“卸载”。我们可以通过<keep-alive>组件强制被切换掉的组件仍然保持“存活状态”

涉及到组件生命周期中的beforUnmounted unmounted

App.vue

<template>

  <!--组件标签-->
  <!--在切换组件后会进入组件卸载的生命周期,原组件的更新信息不会被保存,再次切换时会看见原始的数据-->
  <!-- <component :is="tabComponent"></component> -->

  <!--放在keep-alive中后,则不会进入组件卸载的生命周期,原组件的更新信息会被保存,再次切换时会看见更新过的数据-->
  <keep-alive>
    <component :is="tabComponent"></component>
  </keep-alive>
  
  <button @click="changeHandle">切换组件</button>
</template>
<script>
import ComponentA from "./components/ComponentA.vue";
import ComponentB from "./components/ComponentB.vue";

export default {
  data() {
    return {
      tabComponent:"ComponentB"
    }
  },
  components:{
    ComponentA,
    ComponentB
  },
  methods:{
    changeHandle(){

      // 如果后面的this.tabComponent的值等于ComponentA,则将ComponentB赋给前面的this.tabComponent
      // === 是严格相等,包括类型和值, == 是非严格的相等,通常用在不同类型的值对比
      // this.tabComponent = this.tabComponent=="ComponentA" ?"ComponentB":"ComponentA"
      // 上面的表达式等价于:
      if(this.tabComponent=="ComponentA"){
        this.tabComponent="ComponentB"
      }else{
        this.tabComponent="ComponentA"
      }
    }
  }
}
</script>

ComponentA.vue

<template>
    <h3>ComponentA</h3>
    <p>{{ message }}</p>
    <button @click="updateHandle">更新数据</button>
</template>
<script>

export default{
    data(){
        return{
            message:"更新前的数据"
        }
    },
    methods:{
        updateHandle(){
            this.message="更新后的数据"
        }
    },
    beforeUnmount(){
        console.log("组件被卸载前");
    },
    unmounted(){
        console.log("组件被卸载后");
    }
}
</script>

异步组件

在大型项目中,我们可能需要拆分应用为更小的块,并仅在需要时再从服务器加载相关的组件。vue提供了defineAsyncComponent方法来实现

App.vue

<template>

  <!--组件标签-->
  <!--在切换组件后会进入组件卸载的生命周期,原组件的更新信息不会被保存,再次切换时会看见原始的数据-->
  <!-- <component :is="tabComponent"></component> -->

  <!--放在keep-alive中后,则不会进入组件卸载的生命周期,原组件的更新信息会被保存,再次切换时会看见更新过的数据-->
  <keep-alive>
    <component :is="tabComponent"></component>
  </keep-alive>

  <button @click="changeHandle">切换组件</button>
</template>
<script>
import { defineAsyncComponent } from "vue";
import ComponentA from "./components/ComponentA.vue";
// import ComponentB from "./components/ComponentB.vue";

// 异步加载组件
// 需要手动从vue中引入异步方法defineAsyncComponent,实现在需要ComponentB组件的时候再去请求相关资源
const ComponentB=defineAsyncComponent(()=>
  import("./components/ComponentB.vue")
)

export default {
  data() {
    return {
      tabComponent:"ComponentA"
    }
  },
  components:{
    ComponentA,
    ComponentB
  },
  methods:{
    changeHandle(){

      // 如果后面的this.tabComponent的值等于ComponentA,则将ComponentB赋给前面的this.tabComponent
      // === 是严格相等,包括类型和值, == 是非严格的相等,通常用在不同类型的值对比
      // this.tabComponent = this.tabComponent=="ComponentA" ?"ComponentB":"ComponentA"
      // 上面的表达式等价于:
      if(this.tabComponent=="ComponentA"){
        this.tabComponent="ComponentB"
      }else{
        this.tabComponent="ComponentA"
      }
    }
  }
}
</script>

以上内容出自
【【2023最新版】Vue3从入门到精通,零基础小白也能听得懂,写得出,web前端快速入门教程】 https://www.bilibili.com/video/BV1Rs4y127j8/?share_source=copy_web&vd_source=94c3d5330a46438059359e8dd2494fe9

posted @ 2024-05-14 22:54  PyAj  阅读(79)  评论(0编辑  收藏  举报