首页 > 技术文章 > 关于使用keepalive后清除相关缓存

harryzong 2022-04-15 20:47 原文

我把除temp以外的所有的页面都缓存了      因为发现了一个问题好像是从缓存页面跳往不缓存的页面,清除不掉缓存,只有从不缓存的页面跳往缓存的页面或者缓存页面跳往缓存的页面才能清除缓存(大概是这样,时间久了记不清了,反正记得有点问题)

 

 

 在项目中有一个需求是在切换页面的时候要求保留输入内容,在关闭页面的时候要求清除掉页面的内容

 

 

 

      我尝试了很多方法,最终采用了暴力删除缓存的办法  打印this找到缓存的数据,我在打印的时候发现只有main.js中的this才有,原理不知道,但是我在main.js找到了和网上一样的缓存数据

 

 

 

 懒得整理了,直接复制过来了

 

在main.js中放入以下代码
原理是在路由钩子
beforeRouteLeave(路由离开前的钩子函数)触发的时候执行
使用全局混入,在每个页面都混入这个功能,然后我在store中定义一个变量,放我删除的页面路由(这个路由是fullPath)是一个数组(因为我可能会一次删除好几个页面)

 


 


//
使用Vue.mixin的方法拦截了路由离开事件,并在该拦截方法中实现了销毁页面缓存的功能。 Vue.mixin({ beforeRouteLeave: function(to, from, next) { // console.log(to) // console.log(from) // console.log('ppppppppppp') // debugger // console.log(this) // console.log('触发了this') if (this.$store.getters.delRoute.length === 1) { // 如果只删除了一个。 // debugger // console.dir(this.$vnode) // console.log('进来了') if (this.$vnode && this.$vnode.data.keepAlive) { if (this.$vnode.parent && this.$vnode.parent.componentInstance && this.$vnode.parent.componentInstance.cache) { if (this.$vnode.componentOptions) { var key = this.$vnode.key == null ? this.$vnode.componentOptions.Ctor.cid + (this.$vnode.componentOptions.tag ? `::${this.$vnode.componentOptions.tag}` : '') : this.$vnode.key var cache = this.$vnode.parent.componentInstance.cache var keys = this.$vnode.parent.componentInstance.keys if (cache[key]) { if (keys.length) { // console.log('it: ' + this.$store.getters.delRoute[0]) var index = keys.indexOf(this.$store.getters.delRoute[0]) if (index > -1) { // alert(this.$store.getters.delRoute[0]) keys.splice(index, 1) } } delete cache[this.$store.getters.delRoute[0]] } } } } this.$store.commit('tagsView/EMPTYDELROUTE') // this.$destroy() } else { // 删除了多个的话 if (this.$vnode && this.$vnode.data.keepAlive) { // console.log('进来了1') if (this.$vnode.parent && this.$vnode.parent.componentInstance && this.$vnode.parent.componentInstance.cache) { // console.log('进来了2') if (this.$vnode.componentOptions) { // var key1 = this.$vnode.key == null // ? this.$vnode.componentOptions.Ctor.cid + (this.$vnode.componentOptions.tag ? `::${this.$vnode.componentOptions.tag}` : '') // : this.$vnode.key // console.log('进来了3') var cache1 = this.$vnode.parent.componentInstance.cache var keys1 = this.$vnode.parent.componentInstance.keys // if (cache1[key1]) { if (keys1.length) { // console.log('进来了4') // console.log(this.$store.getters.delRoute) for (let i = 0; i < this.$store.getters.delRoute.length; i++) { // console.log('it: ' + this.$store.getters.delRoute[i]) var index1 = keys1.indexOf(this.$store.getters.delRoute[i]) if (index1 > -1) { // console.log('进来了5') // alert(this.$store.getters.delRoute[0]) keys1.splice(index1, 1) delete cache1[this.$store.getters.delRoute[i]] } } this.$store.commit('tagsView/EMPTYDELROUTE') } // } } } } // else { // console.log(this.$vnode) // console.log('打印出this') // if (this.$vnode && this.$vnode.parent.data && this.$vnode.parent.data.keepAlive) { // if (this.$vnode.parent && this.$vnode.parent.parent.componentInstance && this.$vnode.parent.parent.componentInstance.cache) { // var cache2 = this.$vnode.parent.parent.componentInstance.cache // var keys2 = this.$vnode.parent.parent.componentInstance.keys // if (cache2[keys2]) { // if (keys2.length) { // for (let i = 0; i < this.$store.getters.delRoute.length; i++) { // console.log('it: ' + this.$store.getters.delRoute[i]) // var index2 = keys2.indexOf(this.$store.getters.delRoute[i]) // if (index2 > -1) { // // alert(this.$store.getters.delRoute[0]) // keys2.splice(index2, 1) // delete cache2[this.$store.getters.delRoute[i]] // } // } // } // } // } // } // } // this.$store.commit('tagsView/EMPTYDELROUTE') // } } next() } // beforeRouteUpdate: function(to, from, next) { // // if (to.path === from.path) { // // next('/') // // } else { // console.log('触发了beforeRouteUpdate') // next() // // } // } })

因为这个是在路由跳转才会发生的,所以当跳转的是同一个路由的时候(同一个路由,但是不同的参数,产生的不同页面)我们做一下处理

先判断来的页面和去往的页面是否是同路由(也就是同一个path !  不是fullPath哦)如果是的话就先跳往第三个页面,然后从第三个页面调回来,这样就触发了

beforeRouteLeave  这个钩子函数
这个我也是在main.js中写的路由前置守卫,在routee.js中定义一个路由

 


 

// 这是temp.vue  第三方页面,一进入页面就触发mounted钩子函数跳回去

<template> <div>hello world</div> </template> <script> export default { name: 'temp', data () { return {} }, // beforeRouteEnter (to, from, next) { // console.log(to.path, from.path) // const tmp = to // to = from // next(from.path) // }, created: function () { }, mounted() { const toPath = this.$route.query.toPath console.log(toPath) if (toPath) { console.log('从temp调回去') this.$router.push({ path: toPath }) } }, methods: {} } </script> <style scoped></style>

 

router.beforeEach((to, from, next) => {
  setTimeout(() => {
    if (to.path === from.path) {  // 判断来的路由和去往的路由是否一致,如果一致就跳往第三方页面
      // console.log('跳往了/temp')
      return next({
        path: '/temp',
        query: {
          toPath: to.fullPath
        }
      })
    } else {
      // 如果用户未能验证身份,则 `next` 会被调用两次
      next()
    }
  }, 100)
})

 

 第二种解决方案
https://juejin.cn/post/6876100071826391054
这个没有具体看,但是也能实现删除缓存的效果

推荐阅读