大家好。购物篮。患者配置 - 没有水龙头,都在一个文件中。在加载应用程序时,vuex 商店通过异步操作(Ok)从服务器接收产品目录数据,初始化客户的购物车(localstorage 或 {})(Ok)。对篮子的进一步工作是同步进行的,所以我不再使用动作,我通过突变来行动。我使用 Chrome 的 vue.devtools 进行跟踪和测试。这是存储库代码:
Vue.use(Vuex);
const store = new Vuex.Store({
state: {
customerId: null,
products: {},
cart: {},
},
getters: {
products: state => state.products,
customerId: state => state.customerId,
//cart: state => state.cart,
searchProductsTitle: (state) => (productSearchedTitle) => {
result = {}
if (typeof productSearchedTitle !== 'undefined' && productSearchedTitle != '') {
let m_count = Object.keys(state.products).length
let keys = Object.keys(state.products)
for (i = 0; i < m_count; i++) {
let product = state.products[keys[i]]
if (product.title.toLowerCase().includes(productSearchedTitle.toLowerCase())) Vue.set(result, i, product)
}
}
return result
},
cart_sum: state => {
sum = 0.00
let m_count = Object.keys(state.cart).length
let keys = Object.keys(state.cart)
for (i = 0; i < m_count; i++) {
let item = state.cart[keys[i]]
sum += item[0]['opd'] * item[1]
}
return sum
}
},
mutations: {
'CUSTOMER_ID' (state, id) {
state.customerId = id;
},
'SET_STORE' (state, products) {
state.products = products
},
'SET_CART' (state, cart) {
state.cart = cart
localStorage.shoppingcart = JSON.stringify(state.cart)
},
'ADD_TO_CART' (state, data) {
let id = data[0]['id']
let amount = data[1]
let item = state.cart[id]
if (typeof item == 'undefined') {
item = [data[0], amount]
} else {
item[1] += amount
}
Vue.set(state.cart, id, item)
localStorage.shoppingcart = JSON.stringify(state.cart)
},
'REMOVE_FROM_CART' (state, data) {
let id = data[0]['id']
let amount = data[1]
let item = state.cart[id]
if (typeof item != 'undefined') {
if (item[1] > amount) {
item[1] -= amount
Vue.set(state.cart, id, item)
} else {
Vue.delete(state.cart, id)
}
localStorage.shoppingcart = JSON.stringify(state.cart)
}
},
},
actions: {
initStore: async ({commit}, id) => {...},
},
});
存储组件:
const ShoppingCart = {
template: `
<div id="shopping-cart">
<table class="table">
<thead class="thead-dark">
<tr>
<th scope="col"> </th>
<th scope="col">Title</th>
<th scope="col">Price</th>
<th scope="col">Amount</th>
<th scope="col">Sum</th>
<th scope="col"> </th>
</tr>
</thead>
<tbody>
<tr v-for="(item, index) in cart" v-bind:key="index">
<th scope="row"><img :src="item[0]['media_url']" width="32px" height="32px"></th>
<td>{{ item[0]['title'] }}</td>
<td>₪ {{ item[0]['opd'] }}</td>
<td class="form-inline">
<button class="btn btn-outline-secondary my-sm" type="button"><i class="fa fa-minus" aria-hidden="true" @click="decrCart(item[0], index)"></i></button>
<input class="form-control form-control-sm" type="text" v-model:value="item[1]" readonly size="2" style="text-align: center;">
<button class="btn btn-outline-secondary my-sm" type="button"><i class="fa fa-plus" aria-hidden="true" @click="incCart(item[0], index)"></i></button>
</td>
<td>₪ {{ (item[0]['opd'] * item[1]).toFixed(2) }}</td>
<td><button class="btn btn-outline-danger my-sm" type="button"><i class="fa fa-trash" aria-hidden="true" @click="removeCart(item[0])"></i></button></td>
</tr>
</tbody>
<thead class="thead-light">
<tr>
<th scope="col" colspan="4"> </th>
<th scope="col">₪ {{ (this.totalsum).toFixed(2) }}</th>
<th scope="col"></th>
</tr>
</thead>
</table>
<div class="btn-group btn-group-lg" role="group">
<button type="button" class="btn btn-primary btn-lg" id="go-purchase" :disabled="totulproducts == 0">Go to Purchase!</button>
<button type="button" class="btn btn-outline-danger" id="clear-cart" @click="remove_all()">Remove all</button>
</div>
</div>
`,
computed: {
cart() {
return store.state.cart
},
totalsum() {
return store.getters.cart_sum;
},
totulproducts() {
return Object.keys(this.cart).length;
}
},
methods: {
remove_all() {
store.commit('SET_CART', {});
},
incCart(item, index, amount=1) {
store.commit('ADD_TO_CART', [item, amount]);
},
decrCart(item, index, amount=1) {
store.commit('REMOVE_FROM_CART', [item, amount]);
},
removeCart(item) {
store.commit('REMOVE_FROM_CART', [item, 10000]);
}
},
data: function() {
return {
}
},
}
现在描述问题
当按下 + 和 - 按钮减少或增加购物车中的项目时,devtools 会在 vuex 部分显示数量的变化,但不会在组件的 Computed cart 部分中捕获它(顺便说一下,切换 Vue 时.devtools 贡献,组件的状态立即更新!)。同时,点击“从购物车中完全移除商品”按钮工作正常,立即清理 vuex 和组件,以及组件的渲染。在数量减少到零的情况下类似的正确响应。它不适用于已在篮子中的商品的计算。
没有重新计算篮子的总量(即使在切换 vue.devtools 选项卡或在目录和篮子之间切换到 FE 之后 - 即切换动态组件 - 而篮子的状态更改为正确的状态,即也就是说,当组件启动时,它会从篮子中读取,并且 getter 收到的总金额 - 不,不会改变)。
即使在 vue.devtools 中更新购物车状态,FE 上的渲染也不会改变。
有人告诉我,这三个问题关系密切,但我自己解决不了。经历了很多选择,但被迫向集体思想寻求帮助。
问题完全解决了。在此过程中,用于处理购物篮的系统也进行了重构 - 特别是,不再在其中存储重复的产品,现在购物篮只是具有相同 id 的产品的数量。
这是重构后的 Vuex 代码:
除了 item[0] -> item['product'] 和 item[1] -> item['amount'] 分别之外,组件中没有任何变化。
问题仍然在于分配中间值时失去反应性。也就是说,状态本身似乎是响应式的,当执行中间操作时,getter 不再跟踪更改。