vue中keep-alive的使用及详解

334 阅读2分钟

概念

keep-alive 是 Vue 的内置组件,当它包裹动态组件时,会缓存不活动的组件实例,而不是销毁它们,防止多次渲染。和 transition 相似,keep-alive 是一个抽象组件:它自身不会渲染成一个 DOM 元素,也不会出现在父组件链中。
其拥有两个独立的生命周期钩子函数 actived 和 deactived,使用keep-alive包裹的组件在切换时不会被销毁,而是缓存到内存中并执行 deactived 钩子函数,命中缓存渲染后会执行 actived 钩子函数。

作用

在组件切换过程中将状态保留在内存中,防止重复渲染DOM,减少加载时间及性能消耗,提高用户体验性

原理

在 created 函数调用时将需要缓存的 VNode 节点保存在 this.cache 中/在 render(页面渲染) 时,如果 VNode 的 name 符合缓存条件(可以用 include 以及 exclude 控制),则会从 this.cache 中取出之前缓存的 VNode 实例进行渲染。
VNode:虚拟DOM,其实就是一个JS对象

keep-alive 生命周期

生命周期执行顺序:
1、不使用keep-alive的情况:beforeRouteEnter --> created --> mounted --> destroyed
2、使用keep-alive的情况:beforeRouteEnter --> created --> mounted --> activated --> deactivated
3、使用keep-alive,并且再次进入了缓存页面的情况:beforeRouteEnter -->activated --> deactivated
被keep-alive包裹住的页面都会被缓存,如果想刷新部分内容要启用activated函数,用法同created,activated只有在被keep-alive包裹时会触发,activated函数一进入页面就触发。

props

  • include - 字符串或正则表达,只有匹配的组件会被缓存
  • exclude - 字符串或正则表达式,任何匹配的组件都不会被缓存
  • max - 数字。最多可以缓存多少组件实例。
// 组件 a
export default {
  name: 'a',
  data () {
    return {}
  }
}
<keep-alive include="a">
  <component>
    <!-- name 为 a 的组件将被缓存! -->
  </component>
</keep-alive>可以保留它的状态或避免重新渲染
<keep-alive exclude="a">
  <component>
    <!-- 除了 name 为 a 的组件都将被缓存! -->
  </component>
</keep-alive>可以保留它的状态或避免重新渲染

但实际项目中,需要配合vue-router共同使用

App.vue

<template>
  <div id="app">
    <!-- 路由占位符 -->
    <!-- <router-view></router-view> -->
    <keep-alive>
      <router-view v-if="$route.meta.keepAlive">
        <!-- 这里是会被缓存的视图组件 -->
      </router-view>
    </keep-alive>
 
    <router-view v-if="!$route.meta.keepAlive">
      <!-- 这里是不被缓存的视图组件 -->
    </router-view>
  </div>
</template>

router -> index.js

const routes = [
  { path: '/', redirect: '/index' },
  { path: '/', redirect: '/home' },
  {
    path: '/home',
    component: HomeLayout,
    children: [
      {
        path: '/home',
        component: Home
      },
      {
        path: '/workingCondition',
        component: () =>
          import(
            /*webpackChunkName:"workingCondition"*/ '../views/workingCondition/index.vue'
          ),
        meta: {
          keepAlive: true // 需要被缓存
        }
      }
    ]
  },
  {
    path: '/reportView',
    component: () => import('../views/other/reportView.vue')
  },
  {
    path: '/todo',
    component: () => import(/*webpackChunkName:"ToDo"*/ '../views/ToDo.vue'),
    meta: {
      keepAlive: true // 需要被缓存
    }
  }
]

参考链接

blog.csdn.net/qq_37548296…
blog.csdn.net/fu983531588…