Vue.js实现前进刷新后退不刷新(简洁版)

一、内容概要

以前写过一篇Vue.js单页应用实现前进刷新后退不刷新博客,但在实际的使用的中感觉配置很麻烦,因此查阅资料和阅读他人博客,总结出一套较为简洁的实现方案。

二、方案思路

1.后退不刷新肯定要使用keep-alive
2.前进刷新,有两种情况一种就是进入的页面从未打开过(不用考虑,肯定会刷新),一种是进入的页面已经被打开过,由于使用了keep-alive,如果不做任何处理,进入的页面肯定是不刷新的,还是上一次进入的状态。那么如果被打开过的页面被销毁,再次进入会不会刷新呢?答案是肯定的——会刷新。顺着这个思路,找到页面缓存信息的位置
this.$vnode.parent.componentInstance.cache,this.$vnode.parent.componentInstance.keys以及销毁实例的方法this.$destory()。
3.问题的关键销毁页面时机——执行后退时销毁页面。我这里通过给路由添加level来判断。

三、代码

1.路由文件 level属性标识层级,用于跳转时判断是前进还是后退。

export default [
    {
        name: 'index',
        meta: {
            level: 0,   // 表示层级
        },
        path: '/',
        component: (resolve)=>require(["@/pages/index.vue"], resolve)
    },
    {
        name: 'about',
        meta: {
            level: 1,   // 表示层级
        },
        path: '/about',
        component: (resolve)=>require(["@/pages/about.vue"], resolve)
    },
    {
        name: 'detail',
        meta: {
            level: 2,   // 表示层级
        },
        path: '/detail',
        component: (resolve)=>require(["@/pages/detail.vue"], resolve)
    }
]

2.全局混入路由守卫beforeRouteLeave

export default {
    data() {
        return {}
    },
    methods: {
        goBack() {
            this.$router.back();
        },
    },
    beforeRouteLeave(to,from,next) {
        // 进入页面的层级小于离开页面的层级(后退)
        if(to.meta.level < from.meta.level) {
            let keys = this.$vnode.parent.componentInstance.keys;
            let cache = this.$vnode.parent.componentInstance.cache;
            let key = keys[keys.length-1];
            // 组件被缓存
            if(cache[key] !== null) {
                delete cache[key];  // 删除缓存
                keys.length--;      // 删除key
            }
            // 销毁组件
            this.$destroy();
        }
        next();
    }
}

3.三个测试使用的文件, number为一个0~100的随机数可以标识页面是否刷新
index.vue

<template>
    <div class="info">
        我是首页我的计数为{{number}}
        <router-link tag="button" to="/about">关于页</router-link>
    </div>
</template>

<script>
export default {
    name: "index",
    data() {
        return {
            number: 0,
        }
    },
    mounted() {
        this.number = (Math.random()*100).toFixed(0);
    }
}
</script>

<style scoped>

</style>

about.vue

<template>
    <div class="info">
        <button @click="goBack">返回</button>
        我是关于页的计数为{{number}}
        <router-link tag="button" to="/detail">详情页</router-link></div>
</template>

<script>
export default {
    name: "about",
    data() {
        return {
            number: 0,
        }
    },
    mounted() {
        this.number = (Math.random()*100).toFixed(0);
    },
}
</script>

<style scoped>

</style>

detail.vue

<template>
    <div class="info">
        <button @click="goBack">返回</button>我是详情页的计数为{{number}}
    </div>
</template>

<script>
export default {
    name: 'detail',
    data() {
        return {
            number: 0,
        }
    },
    mounted() {
        this.number = (Math.random()*100).toFixed(0);
    }
}
</script>

<style scoped>

</style>

4.项目中src的目录结构

|--src
|  |--assets		// 静态资源
|  |--components	// 公共组件
|  |--mixin			// 全局混入
|  |  |--index.js
|  |--pages			// 页面信息
|  |  |--about.vue
|  |  |--detail.vue
|  |  |--index.vue
|  |--router		// 路由信息
|  |  |--index.js
|  |  |--routes.js
|  |--App.vue
|  |--main.js
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值