我正在使用 Vuejs 和 Vuex 构建购物车页面。购物车中的每个项目都应该有一个数量计数器来增加或减少为这个特定项目订购的件数。 当我从主产品页面将产品添加到购物车时,然后访问购物车页面。我点击柜台,产品数量发生了变化,但 UI 没有显示这一变化。它仅在我重新加载页面后显示更改,之后它只能显示对该特定计数器的任何新更改,并且我必须在添加每个产品后重新加载才能使其计数器显示 UI 更改。
这是简化的购物车 Vue 组件:
<template >
<tbody>
<tr v-for="product in cartProducts" :key="product.name">
<td class="quantity">
<i class="fa fa-minus" @click="decreaseQuantity(product)"></i>
<p>{{product.quantity}}</p>
<i class="fa fa-plus" @click="increaseQuantity(product)"></i>
</td>
</tr>
</tbody>
</template>
<script>
export default {
computed: {
cartProducts() {
return this.$store.state.cartProducts;
},
},
methods: {
increaseQuantity(drug) {
const existedDrug = this.cartProducts.find(d => d.id === drug.id);
existedDrug.quantity += 1;
this.$store.dispatch("setUserDataCart", this.cartProducts);
console.log(this.$store.state.cartProducts);
},
decreaseQuantity(drug) {
const existedDrug = this.cartProducts.find(d => d.id === drug.id);
existedDrug.quantity -= 1;
this.$store.dispatch("setUserDataCart", this.cartProducts);
console.log(this.$store.state.cartProducts);
},
},
};
</script>
这是我的 vuex 商店:
import Vue from "vue";
import Vuex from "vuex";
import VuexPersist from "vuex-persist";
Vue.use(Vuex);
const vuexPersist = new VuexPersist({
key: "my-app",
storage: window.localStorage
});
const store = new Vuex.Store({
state: {
cartProducts: []
},
mutations: {
SET_USER_CART(state, data) {
state.cartProducts = data;
}
},
actions: {
setUserDataCart({ commit }, data) {
commit("SET_USER_CART", data);
}
},
plugins: [vuexPersist.plugin]
});
export default store;
我尝试了多种方法,例如使用 mapState
或将状态用作 getter
但没有成功。
谁能确定我做错了什么?
最佳答案
在Vue.js docs :
Computed properties are by default getter-only
您尝试在没有 set method 的情况下更改计算属性的方式. 可能发生的情况是,仅更改对象属性而不创建新属性可能不会触发更新 UI 的 react 。
我实际上建议采用另一种方法并将逻辑移动到商店的变异方法,只传递您需要递增/递减的产品的 ID。并且还使用一种在更新后返回全新对象的方法(比如我用来更改 cartProducts
的 map()
方法。
store.js:
import Vue from "vue";
import Vuex from "vuex";
import VuexPersist from "vuex-persist";
Vue.use(Vuex);
const vuexPersist = new VuexPersist({
key: "my-app",
storage: window.localStorage
});
export default new Vuex.Store({
state: {
cartProducts: [
{
id: 1,
name: "Drug 1",
quantity: 1
},
{
id: 2,
name: "Drug 2",
quantity: 1
}
]
},
mutations: {
INCREMENT(state, productId) {
state.cartProducts = state.cartProducts.map(product => {
if (product.id === productId) {
product.quantity += 1;
}
return product;
});
},
DECREMENT(state, productId) {
state.cartProducts = state.cartProducts.map(product => {
if (product.id === productId) {
product.quantity -= 1;
}
return product;
});
}
},
actions: {
incrementQuantity({ commit }, productId) {
commit("INCREMENT", productId);
},
decrementQuantity({ commit }, productId) {
commit("DECREMENT", productId);
}
},
plugins: [vuexPersist.plugin]
});
购物车.js
<template>
<table>
<tbody>
<tr v-for="product in cartProducts" :key="product.name">
<td class="quantity">
<button @click="decreaseQuantity(product)">decrease</button>
<p>{{ product.quantity || 0 }}</p>
<button @click="increaseQuantity(product)">increase</button>
</td>
</tr>
</tbody>
</table>
</template>
<script>
export default {
computed: {
cartProducts() {
return this.$store.state.cartProducts;
}
},
methods: {
increaseQuantity(drug) {
this.$store.dispatch("incrementQuantity", drug.id);
},
decreaseQuantity(drug) {
this.$store.dispatch("decrementQuantity", drug.id);
}
}
};
</script>
关于javascript - 更新时如何使vuex状态更新UI?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60788909/