ajax 的 Vuex 操作未在计算中更新

Vuex action with ajax not updated in computed

我将 Vue 与 Vuex 一起使用。在一种情况下,我使用 Ajax 来获取表示值。在路上的某个地方,可能在 computed 它不再有反应。

在我的组件中:

props: [ 'x', 'y' ],
template: `
  <div class="presentation">
    {{ presentation }}
  </div>
`,
computed: {
  presentation() {
    return this.$store.getters.presentation({ x: this.x, y: this.y });
  }
}

Vuex 商店:

const store = new Vuex.Store({
  state: {
    table: {
      data: []
    }
  },
...

Vuex 动作:

我用 ajax 和 return 调用 url 一个承诺。我也变态了

actions: {
  save: (context) => {
    let uri = 'some/uri';
    let params = {};
    let value = 'A value';

    return axios
    .post(uri, params)
    .then((response) => {
      context.commit('setPresentation', value);
    })
    .catch((error) => {
      console.log('error');
    })
    .finally(() => {});
  },
},

Vuex 突变:

mutations: {
  setPresentation: (state, value) => {
    let pos = state.table.pos;
    state.table.data[pos.y][pos.x].presentation = value;
  },
}

Vuex getters:

getters: {
  presentation: (state) => (pos) => {
    return state.table.data[pos.y][pos.x].presentation;
  }
},

我已经确定了以下几点:

备注:

问题

您需要使用 Vue.set 而不是 state.table.data[pos.y][pos.x].presentation = value;

详情见https://vuejs.org/v2/guide/list.html#Caveats

尝试使用以下代码更新您的突变:

if (!state.table.data[pos.y]) {
  Vue.set(state.table.data, pos.y, [])
}
Vue.set(state.table.data[pos.y], pos.x, { presentation: value })

OP(原帖)我的一句话:

第一次失败的原因是我只将最后一部分 { presentation: value } 设置为 Vue.set 因为我已经在另一个 [=] 中设置了 pos.ypos.x 40=]呼唤。

为了让 Vue 充分意识到我是否需要设置所有尚未设置状态的更改,Vue.set。所以我需要使用 Vue.set 来设置 pos.ypos.x

又看到一个优秀的.

Vue cannot detect changes to an array when you directly set an item with the index

看起来你的 props 是一个数组。您确定 this.x 和 this.y return 您的 presentation 方法中的正确值吗?

你的突变没问题;那里没有问题。只要对象被 Vue.

观察到,Vue 就会检测到对对象 presentation 属性 的赋值

在大多数情况下,Vue 会自动观察对象,但您需要注意一些怪癖(尤其是数组)。

当您直接使用索引 (docs) 设置项目时,Vue 无法检测到对数组的更改。

我假设您按以下方式填充数组:

for (let y = 0; y < Y_MAX; y++) {
  // This is bad! Vue cannot detect this change
  state.table.data[y] = []

  for (let x = 0; x < X_MAX; x++) {
    // Same as above, Vue cannot detect this change. As a consequence,
    // the object you are assigning to the array will not be observed
    // by Vue! So if you were to mutate the presentation property
    // of this object, Vue won't know about it.
    state.table.data[y][x] = { presentation: '...' }
  }
}

因此,要解决您的问题,您只需要确保您没有通过以下方式改变数组:

array[index] = whatever

您需要这样做:

Vue.set(array, index, whatever)

或者,您可以先构建数组,然后将其分配给 state.table.data last; Vue 将检测赋值,然后递归地观察数组及其中包含的所有内容。

const data = []

for (let y = 0; y < Y_MAX; y++) {
  data[y] = []

  for (let x = 0; x < X_MAX; x++) {
    data[y][x] = { presentation: '...' }
  }
}

// After this assignment, data (and all objects contained within it)
// will be observable
state.table.data = data