【bug】【vue】页面切换keep-alive导致的数据问题

本文介绍如何在Vue项目中利用Vuex状态管理和组件的watch特性来解决因Keep-Alive缓存机制导致的多个页面间数据不同步问题。通过两种方法实现:一是限制数据请求仅在当前页面进行;二是为每个页面存储独立的公共组件参数,确保各页面间参数不干扰。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

每个页面通过computed和watch监测vuex参数,在参数变化时请求ajax更新数据。
在公共组件改变参数时,所有页面都会去重新请求数据,当前页面根据数据重新渲染,但切换回其他页面时,由于keep-alive,页面没有变化。

//vuex  store.js
const state = {
	classes: "",
 	day: "",
}
const mutations = {
  updateClasses(state,payload) {
    state.classes=payload
  },
  updateDay(state,payload) {
    state.day=payload
  },
}
//vue  computed
 classes() {
  return this.$store.state.classes
 },
 day() {
   return this.$store.state.day
 },
 //vue  watch
classes(val) {
    this.updateClassChange()//ajax请求
},
day(val) {
    this.updateDayChange()//ajax请求
}
//公共组件
this.$store.commit('updateClasses', {this.classs})
this.$store.commit('updateDay', {this.day})

解决方法一

第一步:判断此时路由是否是当前页面,避免多余的数据请求,只有当前页面重新请求数据

watch: {
  classes(val) {
    if(this.$route.name=="index") {
      this.updateClassChange()
    }
  },
  day(val) {
    if(this.$route.name=="index") {
      this.updateDayChange()
    }
  }
},

第二部:是用钩子函数activated,每切换路由时重新加载,避免参数变化时页面没有变化

activated() {
 if(this.$route.name=="index"){
     this.init()
   }
 },

该方案问题:参数不变时,虽然不重新渲染,但每次切换路由也会重新请求

解决方法二

在vue为每一个页面存储一个公共组件参数,使个页面参数相互不干扰,keep-alive也不混乱

//vuex  store.js
const state = {
	classesObj:{
    index:"",
    addict:"",
    consume:"",
    mental:""
  },
  dayObj:{
    index:"",
    addict:"",
    consume:"",
    mental:""
  },
}
const mutations = {
 setClassesObj(state,payload){
    if(payload.index){
      state.classesObj.index=payload.index
    }
    if(payload.addict){
      state.classesObj.addict=payload.addict
    }
    if(payload.consume){
      state.classesObj.consume=payload.consume
    }
    if(payload.mental){
      state.classesObj.mental=payload.mental
    }
  },
  setDayObj(state,payload){
    if(payload.index){
      state.dayObj.index=payload.index
    }
    if(payload.addict){
      state.dayObj.addict=payload.addict
    }
    if(payload.consume){
      state.dayObj.consume=payload.consume
    }
    if(payload.mental){
      state.dayObj.mental=payload.mental
    }
  },
}
//vue  computed
classes() {
  return this.$store.state.classesObj[this.$route.name]
},
day() {
  return this.$store.state.dayObj[this.$route.name]
},
 //vue  watch
classes(val) {
    this.updateClassChange()//ajax请求
},
day(val) {
    this.updateDayChange()//ajax请求
}
//公共组件
this.$store.commit('setClassesObj', {[this.$route.name]:this.classs})
this.$store.commit('setDayObj', {[this.$route.name]:this.day})
引用中提到了在Vue.js中使用`<keep-alive>`和`<router-view>`时可能会出现子组件渲染两次的问题,并且这个问题只在Vue 3中出现,Vue 2暂时没有这个问题。这可能是由于动态路由渲染同一个子组件导致`<keep-alive>`失效的问题。`<keep-alive>`会缓存路由名称来缓存匹配的组件,如果路由名称不变,那么DOM不会更新,并且缓存的组件不会执行`onMounted`钩子函数,只会执行`activated`和`deactivated`钩子函数。 然而,根据引用中的说明,可以通过给组件添加`meta: {keepAlive: true/false}`来控制是否缓存该组件。在Vue组件的路由配置中,可以添加`meta`字段并设置`keepAlive`属性为`true`或`false`来实现这个目的。如果`keepAlive`为`true`,则该组件会被缓存,否则不会被缓存。 总结一下,使用`<keep-alive>`和`<router-view>`时可能会出现子组件渲染两次的问题,这是Vue 3的一个bug。但可以通过添加`meta`字段并设置`keepAlive`属性来控制组件是否被缓存。如果想要缓存组件,可以将`keepAlive`设置为`true`,否则设置为`false`。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [关于keep-alive与router-view一起使用,子组件渲染两次](https://blog.youkuaiyun.com/weixin_43914605/article/details/128238471)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *3* [keep-alive、router-view](https://blog.youkuaiyun.com/qq_46302247/article/details/123382612)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值