【问题标题】:Vue3 Vuex state change not updating computed valueVue3 Vuex状态更改不更新计算值
【发布时间】: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[]

标签: nuxt.js vuex vuejs3


【解决方案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 });
  },

【讨论】:

    猜你喜欢
    • 2021-07-09
    • 1970-01-01
    • 2021-06-19
    • 2021-04-25
    • 2020-11-23
    • 2020-09-08
    • 2021-08-24
    • 2020-12-22
    • 2023-03-16
    相关资源
    最近更新 更多