VUE 提供了一个内置的组件 keep-alive来缓存组件内部的状态,避免组件重新渲染组件。但是在开发过程中,并不是所有的组件都需要被缓存,于是就用到keep-alive的两个属性
keep-alive属性:
include - 字符串或正则表达式。只有匹配的组件会被缓存。
exclude - 字符串或正则表达式。任何匹配的组件都不会被缓存。
keep-alive用法
1.缓存不活动的动态组件
<keep-alive>
<component :is="view"></component>
</keep-alive>
2.缓存匹配到的路由
将匹配到的路由下的组件,以及组件包裹的组件,都缓存起来
方式一:vue文件中
<keep-alive>
<router-view></router-view>
</keep-alive>
方式二:router.js
{
path: "/",
redirect: "/index/artical",
component: resolve => require(['@/components/index'], resolve),
meta: {
title: "store.state.nickname",
keepAlive: true// 需要被缓存
}
},
那么问题来了,如果在需要被缓存的组件中,有一部分组件不需要被缓存。
如需要被缓存的组件A中包裹了组件b和c,这时我需要缓存组件A中的b而不缓存c该怎么办呢
解决办法1
<keep-alive include="a">
<component>
<!-- name 为 a 的组件将被缓存! -->
</component>
</keep-alive>可以保留它的状态或避免重新渲染
<keep-alive exclude="a">
<component>
<!-- 除了 name 为 a 的组件都将被缓存! -->
</component>
</keep-alive>可以保留它的状态或避免重新渲染
<keep-alive include="a">
<router-view>
<!-- 只有路径匹配到的视图 a 组件会被缓存! -->
</router-view>
</keep-alive>
**缺点:**需要组件的名称,在较为大型且复杂的企业项目中就比较麻烦。
解决办法2
// routes 配置
export default [
{
path: '/',
name: 'home',
component: Home,
meta: {
keepAlive: true // 需要被缓存
}
}, {
path: '/:id',
name: 'edit',
component: Edit,
meta: {
keepAlive: false // 不需要被缓存
}
}
在页面中
<keep-alive>
<router-view v-if="$route.meta.keepAlive">
<!-- 这里是会被缓存的视图组件,比如 Home! -->
</router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive">
<!-- 这里是不被缓存的视图组件,比如 Edit! -->
</router-view>
升级版
假如现在有这样的需求:有三个页面,文章列表页面,文章详情页面,文章新增页面。从文章新增页面到文章列表页面是要刷新文章列表页面。从文章详情页面到文章列表页面是不需要刷文章列表页面。默认显示文章列表页面(听起来有点绕口哈哈)
这时候要用到beforeRouteLeave
在文章列表页面设置路由
{
path: '/',
name: 'A',
component: A,
meta: {
keepAlive: true // 需要被缓存
}
}
在文章新增页面组件中,设置beforeRouteLeave
export default {
data() {
return {};
},
methods: {},
beforeRouteLeave(to, from, next) {
// 设置下一个路由的 meta
to.meta.keepAlive = false; // 让 文章列表 不缓存,即刷新
next();
}
};
在文章详情页面组件中
export default {
data() {
return {};
},
methods: {},
beforeRouteLeave(to, from, next) {
// 设置下一个路由的 meta
to.meta.keepAlive = true; // 让 文章列表页面 缓存,即不刷新
next();
}
};