vue2.0中提供了一个keep-alive
的组建来缓存组件,避免屡次加载相应的组件,减小性能消耗。vue
keep-alive是Vue的内置组件,能在组件切换过程当中将状态保留在内存中,防止重复渲染DOM,结合vue-router中使用。能够缓存某个view的整个内容。正则表达式
语法:vue-router
<keep-alive>
<component>
<!-- 须要缓存的组件 -->
</component>
</keep-alive>
复制代码
通常有这种需求的都是,第一次进入页面时请求一次数据,后面经过路径切换或者前进/后退进入改页面时,页面都使用的缓存数据,DOM不会刷新。缓存
<!-- a.vue -->
export default {
name: 'test',
data() {
return {
includedComponents: 'test'
}
}
}
复制代码
结合exclude和include来进行条件缓存bash
<keep-alive include="test">
<!-- 将缓存name为test的组件 -->
<component></component>
</keep-alive>
<keep-alive include="a,b">
<!-- 将缓存name为a或者b的组件,结合动态组件使用 -->
<component :is="view"></component>
</keep-alive>
<!-- 使用正则表达式,需使用v-bind -->
<keep-alive :include="/a|b/">
<component :is="view"></component>
</keep-alive>
<!-- 动态判断 -->
<keep-alive :include="includedComponents">
<router-view></router-view>
</keep-alive>
<keep-alive exclude="test">
<!-- 将不缓存name为test的组件 -->
<component></component>
</keep-alive>
复制代码
咱们可能会碰到这样的需求,部分缓存:性能
主页 - 列表页 - 详情页
主页 => 列表页 【列表页不须要缓存】
详情页 => 列表页 【列表页须要缓存】
复制代码
网上有不少关于这个例子的解决方案,可是你们有没有发现这种处理方法存在问题,代码大概是这样的。ui
<keep-alive>
<router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
复制代码
list页面路由this
{
path: '/list',
name: 'list',
component: list,
meta: {
keepAlive: true,
}
}
复制代码
Home页面设置spa
<!-- home.vue -->
export default {
data() {
return {};
},
methods: {},
beforeRouteLeave(to, from, next) {
// 设置下一个路由的 meta
to.meta.keepAlive = false;
// Home 跳转到 list 时,让 list 不缓存,即刷新
next();
}
};
复制代码
detail页面prototype
<!-- detail.vue -->
export default {
data() {
return {};
},
methods: {},
beforeRouteLeave(to, from, next) {
// 设置下一个路由的 meta
to.meta.keepAlive = true;
// detail 跳转到 list 时,让 list 缓存,即不刷新
next();
}
};
复制代码
这种方案的bug:
也就是说只要从 Home => list,list的缓存设置失效,必须经历一次detail => list 才能将keepAlive设置为true,list才能达到缓存效果。
今天想说的重点 最近有一个需求是这样的:
A_1 => A [A页面须要缓存]
B_1 => B [B页面须要缓存]
A => B [B不须要缓存]
B => A [A不须要缓存]
复制代码
这种需求怎么实现呢?最开始的想法是更改keepAlive的方式,最后发现行不通。最后的解决方案是
具体代码: 路由设置
{
path: '/A',
name: 'A',
component: A,
meta: {
keepAlive: true,
}
},
{
path: '/B',
name: 'B',
component: B,
meta: {
keepAlive: true,
}
}
复制代码
main.js中记录上一个路由地址
router.beforeEach((to, from, next) => {
Vue.prototype.beforeRouter = from;
next();
})
复制代码
A.vue页面,
activated() {
const beforeRouterName = this.beforeRouter.name;
if (beforeRouterName && beforeRouterName !== 'A_1') {
// 手动刷新页面
this.$refs.table.reload();
}
},
复制代码
B.vue页面
activated() {
const beforeRouterName = this.beforeRouter.name;
if (beforeRouterName && beforeRouterName !== 'B_1') {
// 手动刷新页面
this.$refs.table.reload();
}
},
复制代码
这样就能够实现只要不是B_1/A_1页面进入到B/A时均可以将页面刷新。可能不是最好的解决方案,
若是你有什么更好的解决方法能够留言; 查看更多相关信息可关注公众号: