9SSSpS55q

23朵毒蘑菇

vue-router使用keep-alive动态缓存页面。一种新的解决方案。

原文章迁移

vue|js|vue-router

2021-05-25 09:40:37 已有版本 1 个 show:0.54kTYPE: blog

首先,在配置router的地方配置meta。

//这里我用的是myKeepAlive,和多人用的是keepAlive,我用这个就是不行,不知道原因
const routes = [
    {
        path: '/',  //首页
        name: 'index',
           component: Index,
        meta: {
            title: '首页',
            myKeepAlive:true,  //表示该组件缓存
        },
    },
]

然后在含有router的路由出口文件中

<template>
    <div>
        <keep-alive :include="keepAliveView">
            <router-view></router-view>
        </keep-alive>
    </div>
</template>
<script>
export default {
    data(){
        return {
            keepAliveView:'',  //需要缓存的组件名称列表,用逗号分隔
        };
    },
    created(){
        this.getKeepAliveView();
    },
    methods:{
        getKeepAliveView(){  //每一帧都获取可缓存列表,防止前进时设置缓存会慢一步
            const self = this;
            requestAnimationFrame(function func(){
                let list = self.$router.options.routes.filter(item=>{
                    return item.meta.myKeepAlive;
                }).map(item=>{
                    return item.component.name;  //这里使用的是组件名。keep-alive是根据组件名判断展示那个组件,如果组件名和路由配置的名称一样可以直接写 item.name (如果配置了路由懒加载的话没有component.name)
                });
                self.keepAliveView = "," + list.join(",");  //必须首部加逗号。
                requestAnimationFrame(func);
            });
        },
    },
}
</script>

当需要缓存时,给相应页面的相应路由myKeepAlive设置为true就行了,不需要缓存时设置为false。

当然,很多需求是前进缓存,后退清除缓存。(这里提供一个简单方法,网上很多都是这样的)

//添加全局路由守卫,用来判断页面前进或是后退
router.beforeEach((to, from, next) => {  //页面跳转后添加时间戳参数
    if (typeof to.query._t !== "undefined") {
        next();
    } else {
        to.query._t = new Date().getTime().toString();
        next(to);
    }
});

在需要用到的地方

watch:{
    $route(to,from){  //当页面返回时将取消缓存
        if (parseInt(to.query._t) < parseInt(from.query._t)){  //表示是返回页面
            if(from.name === this.$options.name){  //如果是当前页面返回的话(this.$options.name是当前组件的名字)
                from.meta.myKeepAlive = false;
            }
        }
    },
},

当页面返回的时候设置它的myKeepAlive为false,为什么不是直接用from或者to,因为返回页面包括从上一个页面返回或者返回当前页面,from,to都可能不是当前出口的路由对象。

这样基本就行了,这里只提供一种思路。