vlambda博客
学习文章列表

Vue3动态、异步组件-keepalive的使用方法

动态组件:让多个组件使用同一个挂载点,并动态切换,这就是动态组件。

动态组件的使用

使用 v-if 判断切换组件

 1<template>
2<div id="app">
3  <button v-for="item in list" :class="{active:currentType===item}" :key="item" @click="ChangeTab(item)">{{item}}</button>
4<!--方案一  使用v-if判断切换组件-->
5  <template v-if="currentType=="home"">
6    <home></home>
7  </template>
8  <template v-else-if="currentType=="category"">
9    <category></category>
10  </template>
11  <template v-else>
12    <about></about>
13  </template>
14
15</div>
16</template>
17
18<script>
19import Home from "./views/Home"
20import Category from "./views/Category";
21import About from "./views/About";
22export default {
23  name"App",
24  components:{Home,Category,About},
25  data(){
26    return{
27      list:["home","about","category"],
28      currentType:"home"
29    }
30  },
31  methods:{
32    ChangeTab(item){
33      this.currentType = item
34    }
35  }
36}
37
</script>
Vue3动态、异步组件-keepalive的使用方法

使用动态组件切换组件

动态组价是使用component组件,通过一个特殊的attribute is来实现
代码示例

 1<template>
2<div id="app">
3  <button v-for="item in list" :class="{active:currentType===item}" :key="item" @click="ChangeTab(item)">{{item}}</button>
4<!--  方案二 使用动态组件切换组件-->
5  <component :is="currentType"></component>
6</div>
7</template>
8
9<script>
10import Home from "./views/Home"
11import Category from "./views/Category";
12import About from "./views/About";
13export default {
14  name"App",
15  components:{Home,Category,About},
16  data(){
17    return{
18      list:["home","about","category"],
19      currentType:"home"
20    }
21  },
22  methods:{
23    ChangeTab(item){
24      this.currentType = item
25    }
26  }
27}
28
</script>
Vue3动态、异步组件-keepalive的使用方法

attribute is的值就是全局注册局部注册的组件

  1. 全局注册

1Vue.component("my-component-name", { /* ... */ })
  1. 局部注册

1var ComponentA = { /* ... */ }
2var ComponentB = { /* ... */ }
3new Vue({
4  el"#app",
5  components: {
6    "component-a": ComponentA,
7    "component-b": ComponentB
8  }
9})

动态组件的传值

Home.vue组件中自定义pageClick事件传递给父组件

 1<template>
2<div class="home"><h2>home组件</h2>{{name}}-{{age}} <button  @click="homeClick">点击发送事件</button> </div>
3</template>
4
5<script>
6export default {
7  name"Home",
8  props:{
9    name:{
10      type:String,
11      default""
12    },
13    age:{
14      type:Number,
15      default18
16    }
17  },
18  emits:["pageClick"],
19  methods:{
20    homeClick(){
21      this.$emit("pageClick")
22    }
23  }
24}
25
</script>

父组件接收子组件传递过来的pageClick事件

 1<template>
2<div id="app">
3  <button v-for="item in list" :class="{active:currentType===item}" :key="item" @click="ChangeTab(item)">{{item}}</button>
4  <component :is="currentType" name="acmen" :age="20" @pageClick="pageClick"></component>
5</div>
6</template>
7
8<script>
9import Home from "./views/Home"
10import Category from "./views/Category";
11import About from "./views/About";
12export default {
13  name"App",
14  components:{Home,Category,About},
15  data(){
16    return{
17      list:["home","about","category"],
18      currentType:"home"
19    }
20  },
21  methods:{
22    ChangeTab(item){
23      this.currentType = item
24    },
25    // 使用子组件传递过来的事件
26    pageClick(){
27      console.log("pageClick")// pageClick
28    }
29  }
30}
31
</script>
Vue3动态、异步组件-keepalive的使用方法

使用 keep-alive

假设,我们还使用以上的三个组件进行切换,我的About.vue组件中加了一个按钮,点击每次加一,当我再次切换到Home.vue组件后,我又切换到About.vue组件,这时候我发现上次点击到10了,现在又变成0,解决这个问题我们要使用keep-alive

使用keep-alive对我们的组件进行一层包裹就可以了

1  <keep-alive>
2    <component :is="currentType" name="acmen" :age="20" @pageClick="pageClick"></component>
3  </keep-alive>

keep-alive 的三种属性

Vue3动态、异步组件-keepalive的使用方法

include使用方法 注意:在使用include的时候,首先要检查自身的name选项

1<script>
2export default {
3  name"Home"
4</script>
5

使用方法 使用,

1  <keep-alive include="home,about">
2    <component :is="currentType" name="acmen" :age="20" @pageClick="pageClick"></component>
3  </keep-alive>

Webpack 分包

Vue3动态、异步组件-keepalive的使用方法

我们在做开发的时候会写很多封装的函数方法,在组件中使用,比如我在项目中新建一个utils文件夹中存入一个math.js里面存放一个简单的例子

1export function sum(n,m){
2    return n+m
3}

我们在main.js中使用这个方法

1import { createApp } from "vue"
2import App from "./12_异步组件的使用/App"
3import {sum} from "../utils/math"
4console.log(sum(10,20))
5createApp(App).mount("#app")
Vue3动态、异步组件-keepalive的使用方法

在打包的时候,它会打包到app.js,中。
我现在希望在打包的时候它会单独的给我打包到一个js
代码如下

 1import { createApp } from "vue"
2import App from "./12_异步组件的使用/App"
3// import {sum} from "../utils/math"
4// console.log(sum(10,20))
5
6//使用import函数导入的模块,后续webpack对其进行打包的时候就会进行分包的操作
7import("../utils/math").then((res)=>{
8  res.sum(10,20)
9})
10createApp(App).mount("#app")
Vue3动态、异步组件-keepalive的使用方法

异步组件的使用

Vue3动态、异步组件-keepalive的使用方法

写法一 返回 Promise

 1<template>
2<div id="app">
3  <h1>App组件</h1>
4  <home></home>
5  <async-about></async-about>
6</div>
7</template>
8
9<script>
10import {defineAsyncComponent} from "vue";
11import Home from "./Home"
12//写法一 返回Promise
13const AsyncAbout = defineAsyncComponent(()=>import("./asyncAbout.vue"))
14export default {
15  name"App",
16  components:{Home,AsyncAbout}
17}
18
</script>

写法二 使用对象写法

 1const AsyncAbout = defineAsyncComponent({
2  loader:()=>import("./asyncAbout"),
3  // 组件在加载的时候,显示一个占位的组件
4  loadingComponent:组件名,
5  //组件在加载的时候,失败显示的组件
6  // errorComponent:组件名,
7  //在我们现在loadingComponent组件之前等待多长时间
8  delay:2000,
9  /**
10   *
11   * @param err 错误信息
12   * @param retry 函数,调用retry尝试重新加载
13   * @param attempts 记录尝试的次数
14   */

15   onError:function (err,retry,attempts){
16
17   }
18})

异步组件和 Suspense 结合使用

1  <suspense>
2<!--    能显示就显示默认的-->
3    <template #default><async-about></async-about></template>
4<!--    不能显示 就显示应急组件-->
5    <template #fallback><loading></loading></template>
6  </suspense>