首页 文章

从同一个动作中调用两个突变

提问于
浏览
1

我正在使用 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');
	}
}

但这并不总是有效,有时它会获取物品,但并非总是如此 .

我也尝试在调度 addToCart 动作后立即从组件本身调度 getCartContent 动作,但这也是同样的问题 .

我怎么解决这个问题?

1 回答

  • 2

    您的 axios 调用是异步的,这意味着当您的 getCartContent 突变触发时,您的 addToCart 突变可能不一定完成 . 因此,有时 getCartContent 不会返回您告诉 axios 立即发送邮件请求的项目并不奇怪 .

    您应该将异步调用移动到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 属性来跟踪项目 .

    但是,如果您确实想在添加项目后发出GET请求,则可以在POST请求完成后删除 addToCart 变异和 dispatch getCartContent 操作:

    addToCart(context, data) {
      axios.post('/api/cart/add', {
        item_id: data.item,
      }).then(() => {
        context.dispatch('getCartContent');
      })
    },
    

相关问题