保留组件状态,避免重新渲染

缓存不活动的组件实例
,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM。
生命周期 用的是
激活/停用
activated
deactivated
include 字符串或正则表达式,只有名称匹配的组件会被缓存
exclude 字符串或正则表达式,任何名称匹配的组件都不会被缓存
max 数字,最多可以缓存多少组件实例

<keep-alive include="test-keep-alive">
//将缓存name为test-keep-alive的组件
    <component></component>
</keep-alive>
<keep-alive include="a,b">
//将缓存name为a或者b的组件,结合动态组件使用
    <component :is="view"></component>
</keep-alive>
<keep-alive :include="/a|b/">
//使用正则表达式,需使用v-bind
    <component :is="view"></component>
</keep-alive>
<keep-alive :include="includedComponents">
  <router-view></router-view>
</keep-alive>
<keep-alive exclude="test-keep-alive">
  <!-- 将不缓存name为test-keep-alive的组件 -->
  <component></component>
</keep-alive>

结合router-view使用

<keep-alive>
    <router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
//router.js
export default new Router({
  routes: [
    {
      path: '/',
      name: 'Hello',
      component: Hello,
      meta: {
        keepAlive: false // 不需要缓存
      }
    },
    {
      path: '/page1',
      name: 'Page1',
      component: Page1,
      meta: {
        keepAlive: true // 需要被缓存
      }
    }
  ]
})

如何解决keep-alive缓存

第一种

keep-alive生命周期钩子函数:activated、deactivated
activated: 页面第一次进入的时候,
	钩子触发的顺序是created->mounted->activated
deactivated:  页面退出的时候会触发deactivated,
		当再次前进或者后退的时候只触发activated
		
使用<keep-alive>会将数据保留在内存中,
如果要在每次进入页面的时候获取最新的数据,
需要在activated阶段获取数据,
承担原来created钩子中获取数据的任务

第二种

{
    path: '/',
    name: 'A',
    component: A,
    meta: {
        keepAlive: true // 需要被缓存
    }
}

export default {
    data() {
        return {};
    },
    methods: {},
    beforeRouteLeave(to, from, next) {
         // 设置下一个路由的 meta
        to.meta.keepAlive = true;  
        // B 跳转到 A 时,让 A 缓存,即不刷新
        next();
    }
};

export default {
    data() {
        return {};
    },
    methods: {},
    beforeRouteLeave(to, from, next) {
        // 设置下一个路由的 meta
        to.meta.keepAlive = false; 
        // C 跳转到 A 时让 A 不缓存,即刷新
        next();
    }
};

第三种

每次组件渲染的时候,都会执行beforeRouteEnter
beforeRouteEnter(to, from, next){
    next(vm=>{
        console.log(vm)
        // 每次进入路由执行
        vm.getData()  // 获取数据
    })
},

源码层面的理解

源码层面的理解

Logo

基于 Vue 的企业级 UI 组件库和中后台系统解决方案,为数万开发者服务。

更多推荐