Vue中使用Keep-Alive实现复杂页面缓存

Keep-alive

vue2.0中提供了一个keep-alive的组建来缓存组件,避免多次加载相应的组件,减少性能消耗。

keep-alive是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM,结合vue-router中使用。可以缓存某个view的整个内容。

语法:

<keep-alive>
    <component>
        <!-- 需要缓存的组件 -->
    </component>
</keep-alive>
复制代码

一般有这种需求的都是,第一次进入页面时请求一次数据,后面通过路径切换或者前进/后退进入改页面时,页面都使用的缓存数据,DOM不会刷新。

prop
  • include: 字符串或正则表达式。只有匹配的组件会被缓存。
  • exclude: 字符串或正则表达式。任何匹配的组件都不会被缓存。
条件缓存 【prop】
<!-- a.vue -->
export default {
    name: 'test',
    data() {
        return {
            includedComponents: 'test'
        }
    }
}
复制代码

结合exclude和include来进行条件缓存

<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>
复制代码
部分缓存【keepAlive属性】

我们可能会碰到这样的需求,部分缓存:

主页 - 列表页 - 详情页
主页 => 列表页 【列表页不需要缓存】
详情页 => 列表页 【列表页需要缓存】
复制代码

网上有很多关于这个例子的解决方案,但是大家有没有发现这种处理方法存在问题,代码大概是这样的。

<keep-alive>
    <router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>
复制代码

list页面路由

    {
        path: '/list',
        name: 'list',
        component: list,
        meta: {
            keepAlive: true,
        }
    }
复制代码

Home页面设置

<!-- home.vue -->
export default {
    data() {
        return {};
    },
    methods: {},
    beforeRouteLeave(to, from, next) {
         // 设置下一个路由的 meta
        to.meta.keepAlive = false;  
        // Home 跳转到 list 时,让 list 不缓存,即刷新
        next();
    }
};
复制代码

detail页面

<!-- detail.vue -->
export default {
    data() {
        return {};
    },
    methods: {},
    beforeRouteLeave(to, from, next) {
         // 设置下一个路由的 meta
        to.meta.keepAlive = true;  
        // detail 跳转到 list 时,让 list 缓存,即不刷新
        next();
    }
}; 
复制代码

这种方案的bug:

  1. 首次从 Home => list[页面刷新] => detail;
  2. 目前我们处于detail页面;
  3. detail => list[页面刷新] 【为什么呢?因为我们在Home =>list时将list的keepAlive设置为false了】;
  4. 当前处于list页面,
  5. 再次从 list => detail ,然后返回 detail => list[页面没有刷新],缓存成功。

也就是说只要从 Home => list,list的缓存设置失效,必须经历一次detail => list 才能将keepAlive设置为true,list才能达到缓存效果。

结合Keep-alive实现复杂缓存

今天想说的重点 最近有一个需求是这样的:

A_1 => A [A页面需要缓存]
B_1 => B [B页面需要缓存]
A => B [B不需要缓存]
B => A [A不需要缓存]
复制代码

这种需求怎么实现呢?最开始的想法是更改keepAlive的方式,最后发现行不通。最后的解决方案是

  1. 将A,B页面设置为缓存页面
  2. 记录页面的跳转,即上一个页面是哪一个。
  3. 在A,B页面中判断上一个页面不是A_1或者B_1是就手动刷新页面【activated】阶段,因为页面缓存后第二次进入是不会进入created和mounted的。

具体代码: 路由设置

{
    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时都可以将页面刷新。可能不是最好的解决方案,

如果你有什么更好的解决方法可以留言; 查看更多相关信息可关注公众号:

转载于:https://juejin.im/post/5c1783c7f265da614e2bfda4

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值