从同一个动作中调用两个突变
Calling two mutations from the same action
我正在使用 Vuex
商店将所有商品保存在购物车中。
商店中有两项操作:
getCartContent
,它在页面加载时被调用(从后端获取初始内容,后者又从会话中检索数据)
addToCart
,当用户单击 添加到购物车 按钮时,由 <Products>
组件调度。
这两个调用各自的突变(具有相同的名称),因为您不应该直接从组件内部调用突变。
这是商店的样子:
const store = new Vuex.Store({
state: {
items: [],
},
mutations: {
getCartContent(state, data){
axios.get('/api/cart').then(response => {
state.items = response.data;
});
},
addToCart(state, data){
axios.post('/api/cart/add', {
item_id: data.item,
});
}
},
actions: {
getCartContent(context){
context.commit('getCartContent');
},
addToCart(context, data){
context.commit('addToCart', {item: data.item});
}
}
});
这是按预期工作的,但是现在当一个项目被添加到购物车时(从组件内部调度到 addToCart
操作),我希望它调用 getCartContent
突变,以便它从后端获取新的项目列表。
我尝试从同一个动作中进行第二次突变,如下所示:
actions: {
// ...
addToCart(context, data){
context.commit('addToCart', {item: data.item});
context.commit('getCartContent');
}
}
但这并不总是有效,有时它会获取项目但并非总是如此。
我也试过从组件内部调度 getCartContent
动作,就在调度 addToCart
动作之后,但这是同样的问题。
我该如何解决这个问题?
您的 axios
调用是异步的,这意味着您的 addToCart
变更可能不一定在您的 getCartContent
变更触发时完成。因此,有时 getCartContent
不会 return 您告诉 axios
立即 发送 post 请求的项目并不奇怪 之前。
您应该将异步调用移至 vuex 操作:
actions: {
getCartContent(context, data) {
axios.get('/api/cart').then(response => {
state.items = response.data;
context.commit('getCartContent', response.data),
});
},
addToCart(context, data) {
axios.post('/api/cart/add', {
item_id: data.item,
}).then(() => {
context.commit('addToCart', data.item)
})
},
}
你的突变应该只对模块状态进行简单、直接的更改:
mutations: {
getCartContent(state, items) {
state.items = items;
},
addToCart(state, item) {
state.items.push(item);
}
}
上面的解释假设不是在每个 POST 请求之后发出 get('/api/cart')
请求,而是通过将数据推送到 state.items
[=40] 来跟踪项目=].
但是,如果您真的想在添加项目后发出 GET 请求,您可以去掉 addToCart
突变和 dispatch
getCartContent
之后的操作 POST 请求完成:
addToCart(context, data) {
axios.post('/api/cart/add', {
item_id: data.item,
}).then(() => {
context.dispatch('getCartContent');
})
},
我正在使用 Vuex
商店将所有商品保存在购物车中。
商店中有两项操作:
getCartContent
,它在页面加载时被调用(从后端获取初始内容,后者又从会话中检索数据)addToCart
,当用户单击 添加到购物车 按钮时,由<Products>
组件调度。
这两个调用各自的突变(具有相同的名称),因为您不应该直接从组件内部调用突变。
这是商店的样子:
const store = new Vuex.Store({
state: {
items: [],
},
mutations: {
getCartContent(state, data){
axios.get('/api/cart').then(response => {
state.items = response.data;
});
},
addToCart(state, data){
axios.post('/api/cart/add', {
item_id: data.item,
});
}
},
actions: {
getCartContent(context){
context.commit('getCartContent');
},
addToCart(context, data){
context.commit('addToCart', {item: data.item});
}
}
});
这是按预期工作的,但是现在当一个项目被添加到购物车时(从组件内部调度到 addToCart
操作),我希望它调用 getCartContent
突变,以便它从后端获取新的项目列表。
我尝试从同一个动作中进行第二次突变,如下所示:
actions: {
// ...
addToCart(context, data){
context.commit('addToCart', {item: data.item});
context.commit('getCartContent');
}
}
但这并不总是有效,有时它会获取项目但并非总是如此。
我也试过从组件内部调度 getCartContent
动作,就在调度 addToCart
动作之后,但这是同样的问题。
我该如何解决这个问题?
您的 axios
调用是异步的,这意味着您的 addToCart
变更可能不一定在您的 getCartContent
变更触发时完成。因此,有时 getCartContent
不会 return 您告诉 axios
立即 发送 post 请求的项目并不奇怪 之前。
您应该将异步调用移至 vuex 操作:
actions: {
getCartContent(context, data) {
axios.get('/api/cart').then(response => {
state.items = response.data;
context.commit('getCartContent', response.data),
});
},
addToCart(context, data) {
axios.post('/api/cart/add', {
item_id: data.item,
}).then(() => {
context.commit('addToCart', data.item)
})
},
}
你的突变应该只对模块状态进行简单、直接的更改:
mutations: {
getCartContent(state, items) {
state.items = items;
},
addToCart(state, item) {
state.items.push(item);
}
}
上面的解释假设不是在每个 POST 请求之后发出 get('/api/cart')
请求,而是通过将数据推送到 state.items
[=40] 来跟踪项目=].
但是,如果您真的想在添加项目后发出 GET 请求,您可以去掉 addToCart
突变和 dispatch
getCartContent
之后的操作 POST 请求完成:
addToCart(context, data) {
axios.post('/api/cart/add', {
item_id: data.item,
}).then(() => {
context.dispatch('getCartContent');
})
},