六十天前端强化训练之第二十七天之Pinia 状态管理全解与购物车实战案例

devtools/2025/3/25 2:39:36/

=====欢迎来到编程星辰海的博客讲解======

看完可以给一个免费的三连吗,谢谢大佬!

目录

Pinia%20%E6%B7%B1%E5%BA%A6%E8%A7%A3%E6%9E%90-toc" name="tableOfContents" style="margin-left:40px">一、Pinia 深度解析

Pinia%20%E6%A0%B8%E5%BF%83%E8%AE%BE%E8%AE%A1-toc" name="tableOfContents" style="margin-left:80px">1. Pinia 核心设计

2. 核心概念图解

3. Store 类型对比

Option Store(选项式)

Setup Store(组合式)

4. 响应式原理

二、购物车状态管理实战

1. 项目结构

2. 核心 Store 实现(stores/cart.js)

3. 商品列表组件(ProductList.vue)

4. 购物车组件(ShoppingCart.vue)

三、实现效果说明

四、学习要点总结

五、扩展阅读推荐

官方资源

优质文章

进阶教程


Pinia%20%E6%B7%B1%E5%BA%A6%E8%A7%A3%E6%9E%90" name="%E4%B8%80%E3%80%81Pinia%20%E6%B7%B1%E5%BA%A6%E8%A7%A3%E6%9E%90" style="background-color:transparent">一、Pinia 深度解析

Pinia%20%E6%A0%B8%E5%BF%83%E8%AE%BE%E8%AE%A1" name="1.%20Pinia%20%E6%A0%B8%E5%BF%83%E8%AE%BE%E8%AE%A1">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>

三、实现效果说明


(图示说明:用户添加商品、调整数量、删除商品时,各组件自动同步状态)

  1. 状态共享:多组件同时访问同一购物车状态
  2. 响应式更新:价格计算实时同步
  3. 操作隔离:商品增减逻辑集中管理
  4. 类型安全:完整的TS类型推断

四、学习要点总结

  1. 核心概念

    • Store 作为状态容器
    • State 定义应用状态
    • Getters 实现派生数据
    • Actions 封装业务逻辑
  2. 最佳实践

    JAVASCRIPT

    // 正确的状态解构方式
    const { count } = storeToRefs(store)
    // 错误的方式(破坏响应式)
    const { count } = store
    
  3. 架构原则

    • 单一职责:每个Store聚焦特定领域
    • 低耦合:组件不直接操作其他Store
    • 高内聚:相关逻辑集中管理
  4. 调试技巧

    JAVASCRIPT

    // 浏览器控制台访问
    const store = useCartStore()
    store.$patch({...})
    store.$subscribe((mutation) => {console.log('状态变更:', mutation)
    })
    

五、扩展阅读推荐

官方资源

  1. Pinia 官方文档
  2. Vue 状态管理指南
  3. Pinia 与 Vuex 对比指南

优质文章

  1. 深入理解 Pinia 架构设计
  2. 企业级 Pinia 最佳实践
  3. Pinia 插件开发指南
  4. SSR 场景下的 Pinia 使用
  5. Pinia 单元测试全攻略

进阶教程

JAVASCRIPT

// 持久化插件示例
import { createPinia } from 'pinia'
import { createPersistedState } from 'pinia-plugin-persistedstate'const pinia = createPinia()
pinia.use(createPersistedState({auto: true, // 自动持久化所有Storestorage: sessionStorage
}))

建议运行示例并通过 Vue Devtools 观察状态变更过程,加深理解。义和测试用例。


http://www.ppmy.cn/devtools/170498.html

相关文章

简介S参数 .snp文件

什么是.snp文件 TouchStone格式文件也就是我们通常是到的SnP文件,用来表示S参数。它是用来保存N端口网络有源设备或者无源连接的参数。在实际中,通常用于储存多端口器件的散射参数。 S参数(散射参数,Scattering Parameters)文件采用.snp格式,其中n表示端口数,例如: s1…

使用LangChain开发智能问答系统

代码地址见文末 1. 项目配置 1.1 Neo4j 数据库配置 1. 安装与环境变量 解压路径:将neo4j-community-5.x.x.zip解压至D:\neo4j-community-5.x.x环境变量: NEO4J_HOME: D:\neo4j-community-5.x.xJAVA_HOME: D:\neo4j-community-5.x.x\jdk(注意:需指向 JDK 目录)Path 变量…

关于MTU的使用(TCP/IP网络下载慢可能与此有关)

参考链接&#xff1a;告诉你mtu值怎么设置才能网速最好&#xff01; -Win7系统之家 出现网络速度被限制&#xff0c;可能与MTU值相关&#xff0c;先查看下本机的MTU winR,然后输入&#xff1a;netsh interface ipv4 show subinterfaces &#xff0c;查看自己网络中的MTU&…

FreeRTOS删除任务

原型 void vTaskDelete(TaskHandle_t xTaskToDelete); 不过频繁删除、创建任务&#xff0c;会导致内存碎片&#xff01;&#xff01;

UE AI 模型自动生成导入场景中

打开小马的weix 关注下 搜索“技术链” 回复《《动画》》 快速推送&#xff1b; 拿到就能用轻松解决&#xff01;帮忙点个关注吧&#xff01;

Pytorch使用手册—自定义 C++ 和 CUDA 扩展(专题五十二)

提示 从 PyTorch 2.4 开始,本教程已被废弃。请参考 PyTorch 自定义操作符,了解关于通过自定义 C++/CUDA 扩展扩展 PyTorch 的最新指南。 PyTorch 提供了大量与神经网络、任意张量代数、数据处理等相关的操作。然而,您可能仍然会发现自己需要一个更自定义的操作。例如,您可能…

JVM垃圾回收笔记02-垃圾回收器

文章目录 前言1.串行(Serial 收集器/Serial Old 收集器)Serial 收集器Serial Old 收集器相关参数-XX:UseSerialGC 2.吞吐量优先(Parallel Scavenge 收集器/Parallel Old 收集器)Parallel Scavenge 收集器Parallel Old 收集器相关参数-XX:UseParallelGC ~ -XX:UseParallelOldGC-…

3-22 vector的使用详解---STL C++

C中的vector容器展开系统讲解&#xff0c;具体内容如下&#xff1a; 1. vector的定义和特性&#xff08;基础概念&#xff09; 讲解vector作为动态数组的核心特性&#xff1a;自动内存管理、动态扩容机制&#xff08;倍增策略&#xff09;对比普通数组&#xff1a;支持随机访…