我在我的简单测试电子商务项目中使用Vue2和Vuex。我有默认价格为0美元的产品。在“产品显示”视图中,我有一个计算属性,用于计算用户选择大小度量时的价格。计算正在工作,我可以将calculatedPrice显示到我的视图中,但我很难重新更新商店的property.price值。当我添加到cart时,它会添加默认的$0。
app.js
require('./bootstrap');
import Alpine from 'alpinejs';
window.Alpine = Alpine;
Alpine.start();
import Vue from "vue";
import VuexPersist from 'vuex-persist';
import Vuex from "vuex";
Vue.use(Vuex);
import VueRouter from "vue-router";
Vue.use(VueRouter);
const router = new VueRouter({
mode: 'history',
routes: require('./routes.js')
});
const vuexLocalStorage = new VuexPersist({
key: 'vuex', // The key to store the state on in the storage provider.
storage: window.sessionStorage, // or window.sessionStorage or localForage
// Function that passes the state and returns the state with only the objects you want to store.
// reducer: state => state,
// Function that passes a mutation and lets you decide if it should update the state in localStorage.
// filter: mutation => (true)
})
const store = new Vuex.Store({
state: {
products: [],
cart: [],
order: {}
},
plugins: [vuexLocalStorage.plugin],
mutations: {
updateProducts(state, products) {
state.products = products;
},
addToCart(state, product) {
let productInCartIndex = state.cart.findIndex(item => item.slug === product.slug);
if (productInCartIndex !== -1) {
state.cart[productInCartIndex].quantity++;
return;
}
product.quantity = 1;
state.cart.push(product);
},
removeFromCart(state, index) {
state.cart.splice(index, 1);
},
updateOrder(state, order) {
state.order = order;
},
updateCart(state, cart) {
state.cart = cart;
}
},
actions: {
getCategories({commit}) {
// fetch the categories and attached products from the api
axios.get('/api/products')
.then((response) => {
commit('updateProducts', response.data);
})
.catch((error) => console.error(error));
},
clearCart({commit}) {
commit('updateCart', []);
}
}
});
const app = new Vue({
router,
store,
el: '#app',
created() {
store.dispatch('getCategories')
.then(_ => {})
.catch((error) => console.error(error));
}
});Show.vue
<template>
...
<div class="mt-3">
<h2 class="sr-only">Product information</h2>
<p v-text="formatCurrency(product.price)" class="text-3xl text-gray-900"></p>
</div>
...
<div class="mt-6">
<h3>Size</h3>
<div class="grid grid-cols-4 gap-4">
<div class="mt-4 sm:mt-0 sm:pr-9">
<label for="width" class="block text-sm font-medium text-gray-700">Outer Width:</label>
<select v-model="width" id="width" name="width"
class="mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md">
<option value="3">3"</option>
<option value="4">4"</option>
<option value="5">5"</option>
</select>
</div>
<div class="mt-4 sm:mt-0 sm:pr-9">
<label for="height" class="block text-sm font-medium text-gray-700">Outer
Height:</label>
<select v-model="height" id="height" name="height"
class="mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md">
<option value="3">3"</option>
<option value="4">4"</option>
<option value="5">5"</option>
</select>
</div>
<div class="mt-4 sm:mt-0 sm:pr-9">
<label for="length" class="block text-sm font-medium text-gray-700">Length:</label>
<select v-model="length" id="length" name="length"
class="mt-1 block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md">
<option value="10">10'</option>
<option value="11">11'</option>
<option value="12">12'</option>
</select>
</div>
</div>
</div>
...
</template>
<script>
export default {
methods: {
formatCurrency(amount) {
amount = (amount / 100);
return amount.toLocaleString('en-US', {style: 'currency', currency: 'USD'});
},
},
computed: {
products() {
return this.$store.state.products;
},
product() {
return this.products.find(product => product.slug === this.$route.params.slug);
},
calculatedPrice() { // I need to update product.price in store with this value
return ((((this.width + (this.height * 2)) * 12) / 144) * 25) * this.length;
},
},
data() {
return {
height: '4',
width: '4',
length: '10'
}
}
}
</script>发布于 2022-08-10 02:52:40
在我看来,这个代码段似乎非常可疑,因为它不会触发vue的反应系统。
addToCart(state, product) {
let productInCartIndex = state.cart.findIndex(item => item.slug === product.slug);
// ...
}我宁愿尝试克隆对象并使用Vue.set。就像这样。
import Vue from "vue";
{
addToCart: (state, product) => {
let productInCartIndex = state.cart.findIndex(
(item) => item.slug === product.slug
);
if (productInCartIndex !== -1) {
const target = { ...state.cart[productInCartIndex] };
target.quantity++;
Vue.set(state.cart, productInCartIndex, target);
return;
}
state.cart.push({ ...product, quantity: 1 });
};
}https://stackoverflow.com/questions/73298322
复制相似问题