zl程序教程

您现在的位置是:首页 >  前端

当前栏目

Vue学习第32天——缓存路由组件keep-alive的用法及路由组件独有的2个生命周期函数

Vue路由组件缓存学习 用法 32 生命
2023-09-11 14:21:26 时间

一、keep-alive概念

1、概念

<keep-alive> 包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们。和 <transition> 相似,<keep-alive> 是一个抽象组件:它自身不会渲染一个 DOM 元素,也不会出现在组件的父组件链中。

2、理解

主要用于保留组件状态或避免重新渲染。(让不展示的路由组件保持挂载,不被销毁)
默认情况下,在切换路由时,不展示的组件会被销毁掉,每次切换路由都是一次重新挂载

3、用法

<keep-alive>
    <router-view></router-view>
</keep-alive>

4、配置项

① include
include - 字符串或正则表达式,只有名称匹配的组件才会被缓存
include = "Cats" 名称是Cats的路由组件会被缓存

<!-- 逗号分隔字符串 -->
<keep-alive include="Cats,Dogs"> //Cats和Dogs组件都缓存
  <router-view></router-view>
</keep-alive>

<!-- 正则表达式 (使用 `v-bind`) -->
<keep-alive :include="/Cats|Dogs/"> //Cats和Dogs组件都缓存
  <router-view></router-view>
</keep-alive>

<!-- 数组 (使用 `v-bind`) -->
<keep-alive :include="['Cats', 'Dogs']"> //Cats和Dogs组件都缓存
  <router-view></router-view>
</keep-alive>

匹配首先检查组件自身的 name 选项,如果 name 选项不可用,则匹配它的局部注册名称 (父组件 components 选项的键值)。匿名组件不能被匹配。

② exclude
exclude - 字符串或正则表达式,任何名称匹配的组件都不会被缓存
exclude = "Cats"名称是Cats的路由组件不会被缓存

③ max (2.5.0新增)
max - 数字。最多可以缓存多少组件实例。
部分组件没有name属性,导致如果使用exclude,改动的比较大,所以使用max属性,最多可以缓存多少组件的实例。max属性值必须大于0才能有效。

<keep-alive max="2"> 
  <router-view></router-view>
</keep-alive>

二、案例练习

需求:切换路由组件时,Cats组件一直保持挂载状态,Dogs组件会被挂载与销毁

router/index.js代码

import Vue from "vue";
import VueRouter  from "vue-router";

Vue.use(VueRouter);

import Cats from "../pages/Cats";
import Dogs from "../pages/Dogs"

export default new VueRouter({
    routes:[
        {
            path:'/cats',
            component:Cats,
        },
        {
            path:'/dogs',
            component:Dogs,
        },
    ]
})

App.vue代码

<template>
  <div id="app">
    <h3>动物学院</h3>
      <router-link to="/cats">喵喵学院</router-link>&ensp;
      <router-link to="/dogs">汪汪学院</router-link>
       <!-- Cats路由组件保持挂载 -->
      <keep-alive include = "Cats">
        <router-view></router-view>
      </keep-alive>
  </div>
</template>

<script>

export default {
  name: 'App',
}
</script>

Cats.vue代码

<template>
  <div>
    <p>我是喵喵学院成员</p>
    <input type="text" placeholder="请输入文字">
  </div>
</template>

<script>
export default {
  name:"Cats",
}
</script>

Dogs.vue代码

<template>
  <div>
    <p>我是狗狗学院成员</p>
    <input type="text" placeholder="请输入文字">
  </div>
</template>

<script>
export default {
  name:"Dogs",
}
</script>

运行结果
在这里插入图片描述

三、路由组件中独有的2个生命周期钩子

1、作用

路由组件所特有的2个生命周期函数,用于捕获路由组件的激活状态

2、具体钩子

当组件在<keep-alive>内被切换,它的 activated 和 deactivated 这两个生命周期钩子函数将会被对应执行。
① activated
被 keep-alive 缓存的路由组件激活时调用,该钩子在服务器端渲染期间不被调用
② deacivated
被 keep-alive 缓存的组件失活时调用,该钩子在服务器端渲染期间不被调用。

3、用法

activateddeacivated2个生命周期钩子都必须配合<keep-alive>标签使用

四、2个生命周期钩子案例

需求:在以上案例的基础上,在Cats组件中加入动画和定时器,当从Cats组件切走时,定时器结束

Cats.vue组件代码如下,其余组件不变

<template>
  <div>
    <p>我是喵喵学院成员</p>
    <p :style="{opacity}">喵喵在线闪动</p>
    <input type="text" placeholder="请输入文字">
  </div>
</template>

<script>
export default {
  name:"Cats",
  data() {
    return {
      opacity:0
    }
  },
  beforeDestroy(){
    clearInterval(this.timer)
  },
  mounted() {
   this.timer = setInterval(() => {
      console.log("定时器一直在运行");
      this.opacity += 0.01;
      if(this.opacity >= 1) {
        this.opacity = 0
      }
   }, 16);
  },
  activated(){

  }
}
</script>

运行结果
(我们可以看到,使用<keep-alive>缓存组件时,定时器一直会运行,造成内存消耗)
在这里插入图片描述

改进代码

将 mounted 和 beforeDestroy 两个钩子换成 activated 和 deactivated 钩子

  activated() {
   this.timer = setInterval(() => {
      console.log("定时器一直在运行");
      this.opacity += 0.01;
      if(this.opacity >= 1) {
        this.opacity = 0
      }
   }, 16);
  },
  deactivated(){
    clearInterval(this.timer)
  }

运行结果
在这里插入图片描述

五、总结

1、< keep-alive > 可以让不展示的路由组件保持挂载,不被销毁

2、当组件在< keep-alive >内切换,它的 activated 和 deactived 这两个生命周期钩子函数将会被对应执行。

3、如果同时使用include,exclude,那么exclude优先于include, 下面的例子Cats组件不会被挂载

<keep-alive include="Cats" exclude="Cats">
  <router-view></router-view>
</keep-alive>