3

在项目里经常会遇到以下情况,填单页跳转到选择信息页(eg:选择地址、选择证件),再返回到填单页时,填单页信息不变。可以使用Vue的内置的keep-alive缓存组件来实现以上功能。

1. 使用

在App.vue中加入keep-alive

<template>
    <div id="app">
        <keep-alive>
            <router-view v-if="$route.meta.keepAlive" />
        </keep-alive>
        <router-view v-if="!$route.meta.keepAlive" />
        <TabBar />
    </div>
</template>

在路由文件中,给需要缓存的页面加上meta

{
    path: '/fillorder/:code',
    name: 'fillorder',
    component: Fillorder,
    meta: {
        keepAlive: true,
    },
},

2. 销毁

以上操作已经可以实现填单页的缓存,但是页面加载一次后变不会再重新请求数据,这并不能满足我们的需求。我们希望填单页返回到上一页再进入填单页时页面会重新加载。
所以,我们首先尝试在组件内的路由守卫,通过页面的去向改变该页面的keepAlive

beforeRouteLeave(to, from, next) {
    if (to.name === 'selectAddr') {
        from.meta.keepAlive = true;
    } else {
        from.meta.keepAlive = false;
    }
    next();
},

然后,再次进入页面可以重新加载。但是由于页面进入时是 keepAlive: false,所以会导致出现两个<FillOrder>组件。但问题来了,此时跳转选择地址页面再回到填单页时,显示的填单页是上一次的缓存,这样就导致显示不正确了。

WX20200617-154941@2x.png

keep-alive并未提供销毁包含组件的方法,但我们可以通过比较hack的方式去实现。

function removeKeepAliveCache () {
    if (this.$vnode && this.$vnode.data.keepAlive && this.$vnode.parent) {
        const tag = this.$vnode.tag;
        let caches = this.$vnode.parent.componentInstance.cache;
        let keys = this.$vnode.parent.componentInstance.keys;
        for (let [key, cache] of Object.entries(caches)) {
            if (cache.tag === tag) {
                if (keys.length > 0 && keys.includes(key)) {
                    keys.splice(keys.indexOf(key), 1);
                }
                delete caches[key];
            }
        }
    }
    this.$destroy();
};

然后,在组件里的路由守卫调用removeKeepAliveCache,同时也不需要去修改from.meta.keepAlive

beforeRouteLeave(to, from, next) {
    if (to.name === 'selectAddr') {
        // from.meta.keepAlive = true;
    } else {
        // from.meta.keepAlive = false;
        removeKeepAliveCache.call(this);
    }
    next();
},

至此,就实现了我们开头所说的需求,填单页跳转到选择地址页,再返回到填单页时,填单页信息不变。再次重新进入填单页时,页面会刷新。


蓝胖子呢
4 声望1 粉丝

下一篇 »
[笔记]css揭秘