1、什么是keep-alive
keep-alive是Vue提供给我们的一个内置组件,会缓存不活动的组件实例,而不是销毁它们。作为标签使用包裹这需要缓存的组件。
2、作用
在组件切换过程中,把切换出的组件保存在内存中,防止重新渲染DOM,减少加载时间及性能消耗,提高用户体验。避免左慈重复渲染降低性能
举个例子:
这里有两个组件,Home和About,我们使用钩子函数来显示每个组件的创建和销毁
Home.vue
<template>
<div class="home">
<h1>This is a Home Page</h1>
<input type="text">
</div>
</template>
<script>
export default {
name: "HomePage",
created(){
console.log('Home组件---created');
},
unmounted(){
console.log('Home组件---unmounted');
}
}
</script>
About.vue
<template>
<div class="about">
<h1>This is a About Page</h1>
<input type="text">
</div>
</template>
<script>
export default {
name: "AboutPage",
created(){
console.log('About组件---created');
},
unmounted(){
console.log('About组件---unmounted');
}
}
</script>
App.vue
<template>
<div class="root">
<div class="nav">
<router-link to='/home'>Home</router-link>
<span> | </span>
<router-link to="/about">About</router-link>
</div>
<router-view></router-view>
</div>
</template>
一开始进入Home组件,组件被创建
切换到About组件时,About组件创建,Home组件销毁
但是,如果我需要Home组件被切换掉以后,不销毁,而是保留之前的状态,那么就可以利用keep-alive来实现
keep-alive可以在组件切换时,保存其包裹的组件的状态,使其不被销毁,避免重新渲染。其拥有两个独立的生命周期钩子函数 actived 和 deactived,使用keep-alive包裹的组件在切换时不会被销毁,而是缓存到内存中并执行 deactived 钩子函数,命中缓存渲染后会执行 actived 钩子函数。
<template>
<div class="root">
<div class="nav">
<router-link to='/home'>Home</router-link>
<span> | </span>
<router-link to="/about">About</router-link>
</div>
<router-view v-slot="{ Component }">
<keep-alive>
<component :is="Component" />
</keep-alive>
</router-view>
</div>
</template>
PS:这里Vue3的keep-alive官方进行了修改
原来:
<keep-alive>
<router-view></router-view>
</keep-alive>
现在:
<router-view v-slot="{ Component }">
<keep-alive>
<component :is="Component" />
</keep-alive>
</router-view>
接着,我们在组件Home中输入123456,然后切换到About组件
会发现,Home并没有被销毁
当我们在切换回Home组件时,Home组件也没有重新创建,并且还保留了字符串
这时候,Home组件其实就被缓存了。但同样的,About组件也被缓存了。
如果我们需要设置某某组件不被缓存,或者某某组件需要被缓存,可以利用keep-alive的两个属性
include --- 字符串或正则表达式,只有匹配的组件才会被缓存
exclude --- 字符串或正则表达式,任何匹配的组件都不会被缓存
原写法:
<keep-alive include="HomePage">
<router-view/>
</keep-alive>
Vue3写法:
<router-view v-slot="{ Component }">
<keep-alive include="HomePage">
<component :is="Component" />
</keep-alive>
</router-view>
注意:这里include里面的值不是 路由里定义的,而是组件里的那个name
这时候,就只有Home组件会被缓存,而About组件不会被缓存了。 exclude同理。
实际中,我们更倾向于利用路由的meta属性来控制:
const routes = [
{
name: 'home',
path: '/home',
component: () => import("../View/Home"),
meta:{
keepAlive: true
}
},
{
path: '/about',
component: () => import("../View/About"),
meta: {
keepAlive: false
}
},
]
<router-view v-slot="{ Component }">
<keep-alive>
<component :is="Component" v-if="$route.meta.keepAlive"/>
</keep-alive>
<component :is="Component" v-if="!$route.meta.keepAlive"/>
</router-view>
keep-alive结合v-if,如果meta中的keepAlive为true则缓存,否则不缓存,这样的话更方便且灵活
这样子,就实现了指定组件的缓存,其他组件不缓存。但是,随之而来的问题就是,Home组件被缓存了,我就不知道什么时候离开和什么进入Home组件了。 这时候就要利用 新增的两个钩子函数 activated和deactived来获取当前组件是否处于活动状态。
activated --- 在keep-alive组件激活时调用,该钩子在服务器渲染期间不被调用
deactivated --- 在keep-alive组件停用时调用,该钩子在服务器渲染期间不被调用
只有组件被 keep-alive 包裹时,这两个生命周期函数才会被调用,如果作为正常组件使用,是不会被调用的
<template>
<div class="home">
<h1>This is a Home Page</h1>
<input type="text">
</div>
</template>
<script>
export default {
name: "HomePage",
created(){
console.log('Home组件---created');
},
unmounted(){
console.log('Home组件---unmounted');
},
activated(){
console.log('Home组件---激活');
},
deactivated(){
console.log('Home组件---停用');
}
}
</script>
created ---> activate
版权归原作者 Eric加油学! 所有, 如有侵权,请联系我们删除。