keep-alive的作用

在vue项目中,当路由被频繁切换,路由对应的组件也会在页面上频繁地创建和销毁。
为了避免这种情况的发生,可以使用keep-alive,保留每一个被激活过的组件。
当路由离开,组件不会被销毁,当路由回到时,组件自然也不用创新创建

如何使用keep-alive

在router-view标签的最外层包裹一个 keep-alive 标签就可以了

为大家展示加上keep-alive标签前后的对比

这是不加keep-alive标签的

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

检验Button2组件是否被频繁创建的代码

export default {
  name: 'Button2',
  created: function () {
  	console.log('bnutton2被创建了')
  },
  destroyed: function () {
  	console.log('button2被销毁了')
  }
}

如果切换路由button2组件被创建了,就会打印button2被创建了,如果离开路由组件被销毁了就会打印button2倍销毁了

下面是空置台打印的情况,每一次进入和离开路由,组件就会被创建和销毁一次

keepalived同网段下router_id相同 router keepalive_vue

这是使用keep-alive的情况下

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

检验的方式还是一样,当再次切换路由时,检查控制台情况

keepalived同网段下router_id相同 router keepalive_vue_02


无论如何切换路由的路径,button2始终只是创建的回调函数起了作用,只打印了一次button2被创建了

使用keep-alive的情况下,多出了两个方法可以使用

activated(){
	this.$router.push(this.path)
},
deactivated(){
	this.path = this.$route.path
}

activated就是当组件被激活时
deacctivated 就是当组件取消被激活时
与组件独享守卫有些类似,但是没有组件导航守卫好用,
这两个方法应该是在组件导航守卫的基础上封装而来的

当引入keep-alive的时候,页面第一次进入,钩子的触发顺序created-> mounted-> activated,退出时触发deactivated。当再次进入(前进或者后退)时,只触发activated。

如果使用了keep-alive,又需要更新组件的数据更新,可以将更新数据的语句放到actived钩子函数里面

关于keep-alive标签的属性补充

keep-alive标签有两个属性,include和exclude
include属性表示keep-alive生效的组件,
exclude属性表示keep-alive不会生效的组件

举个例子

<keep-alive include='Button1' exclude='Button2'>
<router-view></router-view>
</keep-alive>

上面的内容表示,当渲染的组件是Button1的时候,只有第一次会创建,离开不会销毁
但渲染组件Button2的时候,每一次都会创建和销毁,
这两个属性适用于部分组件需要每一次都重新创建,根据需求来设置,当然exclude和include属性都可以控制多个组件,只需要用逗号隔开,但千万不要出现空格,因为这是一个字符串解析的过程。

通过meta来解决keep-alive部分组件需要更新数据的问题

<template>
  <div id="app">
    <!--缓存想要缓存的页面,实现后退不刷新-->
    <!--加上v-if的判断,可以自定义想要缓存的组件,自定义在router里面-->
    <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文件加上meta判断
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
export default new Router({
    {//home会被缓存
        path:"/home",
        component:home,
        meta:{keepAlive: true}
    }
    {//hello不会被缓存
        path:"/hello",
        component:hello,
        meta:{keepAlive: false}
    }
})