=====歡迎來到編程星辰海的博客講解======
看完可以給一個免費的三連嗎,謝謝大佬!
目錄
一、Pinia 深度解析
1. Pinia 核心設計
2. 核心概念圖解
3. Store 類型對比
Option Store(選項式)
Setup Store(組合式)
4. 響應式原理
二、購物車狀態管理實戰
1. 項目結構
2. 核心 Store 實現(stores/cart.js)
3. 商品列表組件(ProductList.vue)
4. 購物車組件(ShoppingCart.vue)
三、實現效果說明
四、學習要點總結
五、擴展閱讀推薦
官方資源
優質文章
進階教程
一、Pinia 深度解析
1. Pinia 核心設計
Pinia 是 Vue 官方推薦的新一代狀態管理庫,具有以下核心優勢:
- TypeScript 原生支持:完整的類型推斷和自動補全
- 模塊化架構:天然支持代碼分割和按需加載
- 輕量無冗余:相比 Vuex 減少 40% 的代碼量
- 組合式 API:完美對接 Vue3 的組合式編程范式
- Devtools 整合:完整的時間旅行調試支持
2. 核心概念圖解
3. Store 類型對比
Option Store(選項式)
JAVASCRIPT
export const useCounterStore = defineStore('counter', {state: () => ({ count: 0 }),getters: {double: (state) => state.count * 2,},actions: {increment() {this.count++},}, })
Setup Store(組合式)
JAVASCRIPT
export const useCounterStore = defineStore('counter', () => {const count = ref(0)const double = computed(() => count.value * 2)function increment() {count.value++}return { count, double, increment } })
4. 響應式原理
Pinia 基于 Vue3 的 reactive() 實現響應式系統:
- State 自動轉換為 reactive 對象
- Getters 使用 computed 實現計算緩存
- Actions 作為狀態操作方法
二、購物車狀態管理實戰
1. 項目結構
TEXT
/src├── stores│ └── cart.js├── components│ ├── ProductList.vue│ └── ShoppingCart.vue└── App.vue
2. 核心 Store 實現(stores/cart.js)
JAVASCRIPT
import { defineStore } from 'pinia' import { computed, ref } from 'vue'export const useCartStore = defineStore('cart', () => {// 狀態定義const items = ref([]) // 購物車商品數組const taxRate = 0.1 // 稅率(常量)// Getter(帶參數的派生狀態)const cartTotal = computed(() => items.value.reduce((sum, item) => sum + item.price * item.quantity, 0))const totalWithTax = computed(() => cartTotal.value * (1 + taxRate))// Action:添加商品(冪等操作)const addToCart = (product, quantity = 1) => {const existing = items.value.find(item => item.id === product.id)if (existing) {// 商品存在時增加數量existing.quantity += quantity} else {// 新商品添加購物車items.value.push({...product,quantity,addedAt: new Date().toISOString()})}}// Action:移除商品(支持完全移除和減少數量)const removeFromCart = (productId, quantity = 1) => {const index = items.value.findIndex(item => item.id === productId)if (index === -1) returnif (items.value[index].quantity <= quantity) {// 完全移除商品items.value.splice(index, 1)} else {// 減少商品數量items.value[index].quantity -= quantity}}// Action:清空購物車const clearCart = () => {items.value = []}return {items,cartTotal,totalWithTax,addToCart,removeFromCart,clearCart} })
3. 商品列表組件(ProductList.vue)
VUE
<script setup> import { useCartStore } from '@/stores/cart'const cartStore = useCartStore() const products = [{ id: 1, name: 'Vue T-Shirt', price: 29.99 },{ id: 2, name: 'Pinia Mug', price: 15.50 },{ id: 3, name: 'Vuex Book', price: 39.99 } ] </script><template><div class="product-list"><h2>Available Products</h2><div v-for="product in products" :key="product.id" class="product-item"><h3>{{ product.name }}</h3><p>Price: \${{ product.price.toFixed(2) }}</p><button @click="cartStore.addToCart(product)">Add to Cart</button></div></div> </template>
4. 購物車組件(ShoppingCart.vue)
VUE
<script setup> import { useCartStore } from '@/stores/cart' import { storeToRefs } from 'pinia'const cartStore = useCartStore() const { items, cartTotal, totalWithTax } = storeToRefs(cartStore) </script><template><div class="shopping-cart"><h2>Shopping Cart</h2><div v-if="items.length === 0" class="empty-cart">Your cart is empty</div><div v-else><div v-for="item in items" :key="item.id" class="cart-item"><h3>{{ item.name }}</h3><p>Quantity: {{ item.quantity }}<button @click="cartStore.removeFromCart(item.id, 1)">-</button><button @click="cartStore.addToCart(item)">+</button></p><p>Price: \${{ (item.price * item.quantity).toFixed(2) }}</p><button @click="cartStore.removeFromCart(item.id, item.quantity)">Remove</button></div><div class="totals"><p>Subtotal: \${{ cartTotal.toFixed(2) }}</p><p>Tax (10%): \${{ (totalWithTax - cartTotal).toFixed(2) }}</p><p class="total">Total: \${{ totalWithTax.toFixed(2) }}</p></div><button @click="cartStore.clearCart" class="clear-btn">Clear Cart</button></div></div> </template>
三、實現效果說明
(圖示說明:用戶添加商品、調整數量、刪除商品時,各組件自動同步狀態)
- 狀態共享:多組件同時訪問同一購物車狀態
- 響應式更新:價格計算實時同步
- 操作隔離:商品增減邏輯集中管理
- 類型安全:完整的TS類型推斷
四、學習要點總結
-
核心概念
- Store 作為狀態容器
- State 定義應用狀態
- Getters 實現派生數據
- Actions 封裝業務邏輯
-
最佳實踐
JAVASCRIPT
// 正確的狀態解構方式 const { count } = storeToRefs(store) // 錯誤的方式(破壞響應式) const { count } = store
-
架構原則
- 單一職責:每個Store聚焦特定領域
- 低耦合:組件不直接操作其他Store
- 高內聚:相關邏輯集中管理
-
調試技巧
JAVASCRIPT
// 瀏覽器控制臺訪問 const store = useCartStore() store.$patch({...}) store.$subscribe((mutation) => {console.log('狀態變更:', mutation) })
五、擴展閱讀推薦
官方資源
- Pinia 官方文檔
- Vue 狀態管理指南
- Pinia 與 Vuex 對比指南
優質文章
- 深入理解 Pinia 架構設計
- 企業級 Pinia 最佳實踐
- Pinia 插件開發指南
- SSR 場景下的 Pinia 使用
- Pinia 單元測試全攻略
進階教程
JAVASCRIPT
// 持久化插件示例 import { createPinia } from 'pinia' import { createPersistedState } from 'pinia-plugin-persistedstate'const pinia = createPinia() pinia.use(createPersistedState({auto: true, // 自動持久化所有Storestorage: sessionStorage }))
建議運行示例并通過 Vue Devtools 觀察狀態變更過程,加深理解。義和測試用例。