Vue3 Vuex状态更改不更新计算值

Posted

技术标签:

【中文标题】Vue3 Vuex状态更改不更新计算值【英文标题】:Vue3 Vuex state change not updating computed value 【发布时间】:2021-04-16 19:05:16 【问题描述】:

我遇到了一个难题,即状态更改不会触发组件中的计算值进行更新。我有一个 Finder 组件映射 2 个状态值:车辆 makesmodels,这需要用户选择 make。简而言之,用户选择了正确触发getModels 操作的品牌,但是,计算出的modelsForMake 属性会在商店通过addModelsForMake 更新模型之前被调用。

我只尝试包含必要的代码以了解情况,并且仅供参考,我使用的是 Nuxt,因此我没有组合 API 访问权限。

export default 
  
  beforeCreate() 
    …
    // Loads models for user to load from
    this.$store.dispatch('vehicle/getMakes');
  ,

  computed: 
    ...mapState('vehicle', ['makes', 'models']),

    make: 
      get() 
        return this.$store.state.vehicle.make;
      ,
      set(val) 
        this.$store.commit('vehicle/setMake', val);
      
    

    model: //…similar as make…

    // Gets called after state has updated the make and before models get loaded
    modelsForMake() 
      return this.models[this.make] || [];
    ,
  ,
  watch: 
    make() 
      // Initial trigger: user selected make -> loads models
      this.$store.dispatch('vehicle/getModels', this.make);
    ,
  
  …

这是我的 Vuex 商店

export const state = () => (
  make: '',
  model: '',
  makes: [],
  models: ,
);

export const mutations = 
  setMake(state, make: string) 
    Object.assign(state,  make );
  ,

  …,

  // This gets called after the computed value updated and it doesn't trigger a recompute
  addModelsForMake(state, models: object[]) 
    if (!models.length) 
      return;
    

    const obj = ;
    obj[models[0].make_slug] = models
    Object.assign(state.models, obj);
    // Below is the previous Vue2 fix I'm trying to fix
    // Vue.set(state.models, models[0].make_slug, models)
  ,
  …

export const actions = 
  getModels( commit, state , make) 
    if (state.models[make] || make === null) 
      return Promise.resolve();
    

    return AXios_API.get(`/makes/$make`)
      .then(response => commit('addModelsForMake', response.data)) // models loaded
      .catch(err =>
        console.error(`Failed to get models from the vehicle API: $err`)
      );
  ,
  …

编辑:根据@Daniel 的回复,我尝试将 Object.assign 替换为直接定义,并且发生了相同的顺序不匹配

addModelsForMake(state, models: object[]) 
    if (!models.length) 
      return;
    

    state.models = state.models || ;
    state.models[models[0].make_slug] = models;

【问题讨论】:

make 是对象还是字符串? 是的,make:string,models:object[] 【参考方案1】:

你可以试试

  setMake(state, make) 
    state.make = make
  ,

而不是

  setMake(state, make) 
    Object.assign(state,  make );
  ,

我认为您可能遇到了 Vue 无法检测到更改的问题,因为 Object.assign 改变了第一个参数。假设第一个参数相同,则未检测到更改。如果您想使用Object.assign,另一种选择是首先传递一个空对象,这会将一个新对象重新分配给state,这也会触发更新。

  setMake(state, make) 
    state = Object.assign(, state,  make );
  ,

【讨论】:

以上是关于Vue3 Vuex状态更改不更新计算值的主要内容,如果未能解决你的问题,请参考以下文章

计算值更改时组件不重新渲染

vue3—reactive如何更改属性

Vuex-页面在提交状态更改后未更新

Vuex getter无法更新状态更改

更改表值时Vuex Store不更新

Vuex 提交不更新状态