vue缓存页面keepAlive的坑(数据不刷新,只缓存第一次进入的页面数据),强制刷新缓存的页面的方法

需求:A进入B,根据不同id刷新B页面数据,B进入C,C返回B,如果C有操作数据,则返回B后刷新B数据,否则B页面不刷新;
在这里插入图片描述
第一次尝试
*思路是从C进入B,缓存B,其他页面进入B,不缓存

B页面:

beforeRouteLeave(to, from, next) {
  from.meta.keeplive= false;
  next();
},
activated(){  
    //根据$route.meta
},

C页面

  // 返回上一页路由不刷新问题
  beforeRouteLeave (to, from, next) {
      to.meta.type=this.showChange;
      to.meta.keeplive = true;
         if(this.edit){
           to.meta.isrefer=true;//编辑成功后刷新B页面的数据,状态码
         }else{
         to.meta.isrefer=false;
         }
    next();
  },

理论上没毛病啊,可是问题来了
第一次,A进B,B进C,C返回B,缓存了B

第二次,A进B,B会刷新,B再进C,C再返回B,B的数据是第一次进入B的时候的数据

原因:因为B的页面参数还是第一次缓存的时候的参数,所以,无论怎么重新加载数据,数据还是原来第一进入的B的数据,因为请求的参数从来没有改变。

解决方案一

A页面

	beforeRouteLeave (to, from, next) { 
				  to.meta.isrefer = true;//刷新B的数据
				  to.meta.type=false;
    			next();
  	},

B页面

  beforeRouteEnter(to, from, next){
      to.meta.keeplive= true;
       next(vm=>{
       //这里把页面初始值重新赋值,以刷新页面
       if(vm.$route.meta.isrefer){
        vm.dataList=[];
        vm.$route.meta.isrefer=false;//恢复初始值
        vm.seatList=[]
        vm.query={
                 activityId: vm.$route.query.activityId,
                 meetplaceId: vm.$route.query.meetplaceId,
        }
        vm.getSeatImgList()//请求数据
      }
    })
  },
beforeRouteLeave(to, from, next) {
  from.meta.keeplive= true;//每次进入页面都缓存B
  next();
},

C页面与上面不变

App.vue

	<router-view v-if="$route.meta.keeplive"></router-view>
	</keep-alive>
	<router-view v-if="!$route.meta.keeplive"></router-view>

解决方案二(利用provide和inject)

1、app.vue页面

	<keep-alive v-if="isRouterAlive ">
			<router-view v-if="$route.meta.keeplive"></router-view>
	</keep-alive>
	<router-view v-if="!$route.meta.keeplive"></router-view>

data里面加个初始值

data(){
	return{
		isRouterAlive:true
	}
}

与data同级加个provide

provide() { return { reload: this.reload }; },

method加reload方法

reload() { 
	this.isRouterAlive = false; 
	this.$nextTick(() => (this.isRouterAlive = true)); 
}

2、要缓存的页面

与data同级加个
inject: ["reload"]

修改beforeRouterEnter

  beforeRouteEnter(to, from, next){
      to.meta.keeplive= true;
       next(vm=>{
       		vm.reload()//调用app.vue的方法
       }
    }

解决方案三(利用activated)

 activated(){
       //判断参数是否刷新,后更新页面数据
    }

每一次采坑,都是在进步和学习的过程

### 回答1: Vue页面的keep-alive缓存可以通过以下方法清除: 1. 在组件中使用activated钩子函数,手动清除缓存: ``` activated() { this.$nextTick(() => { this.$refs.keepAliveComponent && this.$refs.keepAliveComponent.clearCache() }) } ``` 2. 在路由配置中使用meta属性,设置需要清除缓存的路由: ``` { path: '/example', name: 'example', component: Example, meta: { keepAlive: false // 设置为false表示不缓存该路由 } } ``` 3. 在组件中使用$route.meta.keepAlive属性,动态设置是否缓存: ``` <template> <div v-if="$route.meta.keepAlive">需要缓存的组件</div> <div v-else>不需要缓存的组件</div> </template> ``` 以上是清除Vue页面keep-alive缓存方法,希望能对你有所帮助。 ### 回答2: Vue中的keep-alive组件可以缓存组件实例,当组件被切换隐藏时,它的状态将被保留,就像在内存中一样。但是,我们会发现在一些情况下,我们需要手动清除keep-alive缓存,以便重新渲染组件。 在Vue中,可以通过以下方式清除keep-alive缓存: 1. keep-alive组件内部方法: 通过在keep-alive组件的内部定义一个clear方法,我们可以手动清除缓存。 例如: <keep-alive ref="keepAlive"> <router-view></router-view> </keep-alive> methods: { clearCache() { this.$refs.keepAlive.cache = {} // 或者用this.$refs.keepAlive.$options.cache = {}, 这两种方法都可以手动清除缓存。 } } 这里,我们通过向keep-alive组件添加ref="keepAlive"来获取组件引用。然后在methods内部定义了一个clearCache方法来清除缓存。在Vue 2.3.0+版本中,keepAlive组件提供了cache属性来存储keepAlive组件缓存,我们可以通过this.$refs.keepAlive.cache={};清空缓存。 2. router钩子函数: 除了在keep-alive组件内部定义clear方法以外,我们还可以通过在router的钩子函数中实现缓存的清除。 例如: const router = new VueRouter({ routes: [ { path: '/', component: Home, meta: { keepAlive: true } }, { path: '/about', component: About } ] }) router.beforeEach((to, from, next) => { if (!to.meta.keepAlive) { clearKeepAliveCache(); } next(); }) function clearKeepAliveCache() { const cache = this.$options.cache; //获取keepAlive缓存对象 Object.keys(cache).forEach(key => { cache[key].instance.$destroy(); //销毁实例 delete cache[key]; //删除缓存 }); } 我们在VueRouter对象的routes选项中定义了meta.keepAlive属性来判断该路由是否需要缓存。接着在router.beforeEach钩子函数中通过判断meta.keepAlive,来决定是否清除keep-alive缓存。调用clearKeepAliveCache函数清除缓存。 清除缓存时,我们需要销毁实例,以避免内存泄漏。 以上是清除Vue 页面keepalive缓存的两种方法,尽管官方文档推荐第一种方法,但是当我们在不同的路由之间切换时,第二种方法较为灵活。 ### 回答3: vue页面中使用keep-alive指令会使得页面缓存,这种缓存机制可以提高页面的性能和用户体验。但是在一些特定的场景下,需要手动清除页面缓存以达到更好的效果。这篇文章将介绍如何清除vue页面中的缓存。 一、全局清除 可以使用以下两种方法来清除vue页面缓存方法1:调用$destroy()方法 在需要清除页面缓存的地方,通过访问Vue的根实例,可以得到keep-alive组件的实例。调用该实例的$destroy()方法即可清除缓存,以下是示例代码: ```javascript this.$root.$children[0].$children.find(item => item.$options.name==='keep-alive').$destroy() ``` 方法2:使用del命令 del命令可以同样实现页面缓存清除功能,这种方法只需要设置对应keep-alive组件的include属性为空数组,如下所示: ```javascript let keepAliveComponentList = this.$refs.keepAlive keepAliveComponentList.forEach(component => { component.include = [] }) ``` 二、局部清除 需要注意的是,全局清除会将所有的vue页面缓存清除,这样会带来繁琐的操作和不必要的性能消耗。因此,推荐使用局部清除来清除vue页面缓存。 下面是一个实现局部清除的示例: ```html <template> <div> <!-- 1. 绑定 $route 参数 --> <keep-alive :include="keepAliveList"> <router-view :key="$route.fullPath"/> </keep-alive> </div> </template> <script> export default { data() { return { keepAliveList: ["home"] } }, created() { let currentName = this.$route.name this.keepAliveList.push(currentName) }, // 2. 监听 $route 对象 watch: { $route(newVal, oldVal) { if (this.keepAliveList.indexOf(newVal.name) === -1) { this.keepAliveList.push(newVal.name) } if (this.keepAliveList.indexOf(oldVal.name) !== -1) { this.keepAliveList.splice(this.keepAliveList.indexOf(oldVal.name), 1) } } } } </script> ``` 以上代码中,我们通过将已经访问过的页面名称加入数组keepAliveList中,然后将该数组绑定到keep-alive组件的include属性上,只有在该数组内的页面才会被keep-alive缓存,不在数组内的页面将会在跳转的时候被销毁。 总结: 缓存机制是前端优化中的一个重要环节,适当的使用keep-alive组件可以减少服务器的压力,提高页面性能。但是在实际应用中,我们需要考虑到缓存的清除问题,根据不同的应用场景,选择全局清除还是局部清除,以最优化的体验来满足用户需求。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值