Vue.js Vuex状態管理
Vuexによる状態管理
Vuexを使ってグローバルな状態管理を実装しよう。商品リストとカートの状態を一元管理します。
タスク
Vuexストアの作成
State、Actions、Mutations、Gettersを定義しよう
コンポーネントでの状態利用
$store.stateや$store.dispatchを使って状態を操作しよう
Gettersでの計算
合計金額をGettersで計算しよう
ヒント
VuexのState、Actions、Mutations、Gettersを使って、コンポーネント間で状態を共有しましょう。
参考コード
// Vuexストアの作成 const store = Vuex.createStore({ state() { return { products: [ { id: 1, name: '商品A', price: 1000 }, { id: 2, name: '商品B', price: 2000 }, { id: 3, name: '商品C', price: 1500 } ], cart: [] } }, mutations: { addToCart(state, product) { const existingItem = state.cart.find(item => item.id === product.id) if (existingItem) { existingItem.quantity++ } else { state.cart.push({ ...product, quantity: 1 }) } }, removeFromCart(state, productId) { state.cart = state.cart.filter(item => item.id !== productId) }, updateQuantity(state, { productId, quantity }) { const item = state.cart.find(item => item.id === productId) if (item) { item.quantity = quantity } } }, actions: { addProduct({ commit }, product) { commit('addToCart', product) }, removeProduct({ commit }, productId) { commit('removeFromCart', productId) }, updateProductQuantity({ commit }, payload) { commit('updateQuantity', payload) } }, getters: { cartTotal: (state) => { return state.cart.reduce((total, item) => total + (item.price * item.quantity), 0) } } }) // 商品リストコンポーネント const ProductList = { computed: { products() { return this.$store.state.products } }, methods: { addToCart(product) { this.$store.dispatch('addProduct', product) } }, template: ` <div> <div v-for="product in products" :key="product.id" class="product-item"> <h4>{{ product.name }}</h4> <p>¥{{ product.price }}</p> <button class="btn" @click="addToCart(product)">カートに追加</button> </div> </div> ` } // ショッピングカートコンポーネント const ShoppingCart = { computed: { cart() { return this.$store.state.cart }, total() { return this.$store.getters.cartTotal } }, methods: { removeItem(productId) { this.$store.dispatch('removeProduct', productId) }, updateQuantity(productId, quantity) { this.$store.dispatch('updateProductQuantity', { productId, quantity }) } }, template: ` <div> <div v-for="item in cart" :key="item.id" class="cart-item"> <h4>{{ item.name }}</h4> <p>¥{{ item.price }} × {{ item.quantity }}</p> <button class="btn" @click="updateQuantity(item.id, item.quantity + 1)">+</button> <button class="btn" @click="updateQuantity(item.id, Math.max(0, item.quantity - 1))">-</button> <button class="btn" @click="removeItem(item.id)">削除</button> </div> <div class="total">合計: ¥{{ total }}</div> </div> ` } // アプリケーションの作成 const app = Vue.createApp({ components: { 'product-list': ProductList, 'shopping-cart': ShoppingCart } }) // Vuexストアをアプリケーションに追加 app.use(store) // マウント app.mount('#app')