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;
}
},
我已经确定了以下几点:
- 我将
table.data
状态设置为默认值以使其响应
- 使用getter获取数据
- 使用 ajax 调用的操作
- 在操作中调用带有提交的突变
备注:
- ajax 调用需要在一个动作中而不是在创建中,因为我要从多个组件中使用
presentation
。
- 我更喜欢不需要外部 Vue 插件的解决方案。
问题
- 我错过了什么?
- 我怎样才能最好地解决它?
您需要使用 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.y
和 pos.x
40=]呼唤。
为了让 Vue 充分意识到我是否需要设置所有尚未设置状态的更改,Vue.set
。所以我需要使用 Vue.set
来设置 pos.y
和 pos.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
我将 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;
}
},
我已经确定了以下几点:
- 我将
table.data
状态设置为默认值以使其响应 - 使用getter获取数据
- 使用 ajax 调用的操作
- 在操作中调用带有提交的突变
备注:
- ajax 调用需要在一个动作中而不是在创建中,因为我要从多个组件中使用
presentation
。 - 我更喜欢不需要外部 Vue 插件的解决方案。
问题
- 我错过了什么?
- 我怎样才能最好地解决它?
您需要使用 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.y
和 pos.x
40=]呼唤。
为了让 Vue 充分意识到我是否需要设置所有尚未设置状态的更改,Vue.set
。所以我需要使用 Vue.set
来设置 pos.y
和 pos.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