【Vue3】【笔记】----第五章:Vue3 状态管理(Pinia 从入门到实战)
·
文章目录
第五章:Vue3 状态管理(Pinia 从入门到实战)
一、入门:为什么用 Pinia?核心概念与环境准备
- Pinia 替代 Vuex 的核心原因:Pinia 是 Vue 官方推荐的状态管理库,相比 Vuex 3/4,它无需模块化嵌套(单个 Store 即可独立使用)、天然支持 TypeScript、API 更简洁(去掉 mutations,直接用 actions 处理同步/异步),且体积更小、性能更优。
- 核心概念:Pinia 只有两个核心概念——Store(存储状态的容器,每个 Store 对应一个业务模块,如用户 Store、购物车 Store)和 Actions(修改状态的方法,支持同步和异步,替代 Vuex 的 mutations 和 actions)。
- 环境搭建:
- 安装:在 Vue3 项目中执行
npm install pinia。 - 全局注册:在
main.js中引入并创建 Pinia 实例,挂载到 app:
import { createApp } from 'vue' import { createPinia } from 'pinia' import App from './App.vue' const app = createApp(App) app.use(createPinia()) // 注册 Pinia app.mount('#app') - 安装:在 Vue3 项目中执行
二、精通:Store 创建与状态操作全流程
- 创建 Store(以“用户 Store”为例):
- 在
src/store文件夹下新建userStore.js,用defineStore定义 Store,第一个参数是唯一 ID(必须,用于 Pinia 内部识别),第二个参数是配置对象:
import { defineStore } from 'pinia' // 函数名建议用 useXXXStore 格式(规范) export const useUserStore = defineStore('user', { // state:存储状态(类似组件的 data) state: () => ({ username: '', token: '', isLogin: false }), // actions:修改状态的方法(支持同步/异步,类似组件的 methods) actions: { // 同步修改:登录成功更新状态 loginSuccess(userInfo) { this.username = userInfo.username // 直接通过 this 访问 state this.token = userInfo.token this.isLogin = true // 持久化存储:将 token 存到 localStorage localStorage.setItem('token', userInfo.token) }, // 异步操作:模拟接口请求登录 async login(data) { // 模拟 axios 请求 // const res = await axios.post('/api/login', data) const res = { code: 200, data: { username: data.username, token: 'xxx123' } } if (res.code === 200) { this.loginSuccess(res.data) // 调用同步 action 更新状态 return true } return false }, // 退出登录:清空状态 logout() { this.username = '' this.token = '' this.isLogin = false localStorage.removeItem('token') } }, // getters:计算属性(类似组件的 computed,自动缓存) getters: { // 拼接欢迎语 welcomeMsg: (state) => `欢迎回来,${state.username || '游客'}` } }) - 在
- 状态操作(在组件中使用 Store):
- 引入并创建 Store 实例:
import { useUserStore } from '@/store/userStore',const userStore = useUserStore()。 - 访问 state:直接用
userStore.username(无需像 Vuex 一样用state.user.username)。 - 调用 actions:
await userStore.login({ username: 'test', password: '123' })(异步 action 需加 await)。 - 访问 getters:
userStore.welcomeMsg(直接调用,无需加括号)。
- 引入并创建 Store 实例:
- 状态重置与修改技巧:
- 重置状态:
userStore.$reset()(将 state 恢复到初始值,适合退出登录等场景)。 - 批量修改状态:用
$patch方法,避免多次修改触发多次更新,例:userStore.$patch({ username: 'newName', isLogin: true })。
- 重置状态:
三、实战:用 Pinia 实现“购物车功能”
- 需求拆解:实现“添加商品到购物车”“修改商品数量”“删除购物车商品”“计算购物车总价”“选择/取消选择商品”功能,且购物车状态需在多个组件(商品详情页、购物车页、导航栏购物车图标)间共享。
- 核心实现(创建
cartStore.js):- state 定义:
cartList: [](存储购物车商品,每个商品包含 id、name、price、count、checked)。 - actions 实现:
addCart(goods):先判断商品是否已在购物车,已存在则增加 count,不存在则添加到 cartList(设置默认 count=1、checked=true)。updateCount(id, count):根据商品 id 找到对应项,更新 count(count 不能小于 1)。deleteCart(id):过滤掉 id 对应的商品,更新 cartList。toggleCheck(id):切换单个商品的 checked 状态;toggleAllCheck(checked):全选/全不选所有商品。
- getters 实现:
totalPrice:计算选中商品的总价(遍历 cartList,累加checked为 true 的商品price * count)。selectedCount:计算选中商品的总数量。isAllChecked:判断是否所有商品都被选中(cartList 不为空且 every 商品 checked 为 true)。
- state 定义:
- 组件中使用:
- 商品详情页:点击“加入购物车”,调用
cartStore.addCart(goodsInfo),并提示添加成功。 - 购物车页:通过
cartStore.cartList渲染商品列表,绑定“数量修改”“删除”“选择”按钮,调用对应 actions;用cartStore.totalPrice显示总价,用cartStore.isAllChecked控制全选框。 - 导航栏:用
cartStore.selectedCount显示购物车图标上的数字,实现状态实时同步。
- 商品详情页:点击“加入购物车”,调用
更多推荐
所有评论(0)