当前位置: 首页 > news >正文

Vue中Pinia和Vuex有什么区别该用哪个

Vue 中 Pinia 和 Vuex 有什么区别?该用哪个?

一句话总结:Pinia 是 Vue 3 官方推荐的状态管理库,比 Vuex 更轻、更简洁、TypeScript 支持更好。新项目直接 Pinia,老项目逐步迁移,别犹豫!


正文目录

  1. Pinia 和 Vuex 的核心区别
  2. 5 大高频踩坑场景 & 迁移代码
  3. 万能兜底:Pinia 标准 Store 模板
  4. 预防 checklist(不再踩坑)
  5. 一句话总结

一、Pinia 和 Vuex 的核心区别

对比项Vuex 4Pinia
Vue 版本Vue 2 / Vue 3Vue 2 / Vue 3
Store 定义state + getters + mutations + actionsstate + getters + actions(无 mutations)
TypeScript 支持一般,需要大量类型断言优秀,自动类型推断
模块化需要modules嵌套每个 Store 独立,天然扁平
Composition API需要适配原生支持 setup 语法
体积~10KB~6KB
DevTools 支持
学习成本高(mutations 概念冗余)低(直觉式 API)

一句话:Pinia 砍掉了 mutations,每个 Store 独立定义,setup 语法天然支持,TS 类型自动推断。新项目无脑选 Pinia。


二、5 大高频踩坑场景 & 迁移代码

① Vuex 习惯:修改 state 必须走 mutations
// ❌ Vuex 习惯:修改 state 必须写 mutationconststore={state:()=>({count:0}),mutations:{increment(state){state.count++;}},actions:{asyncIncrement({commit}){commit('increment');// ❌ Pinia 不需要 commit}}};// 组件里this.$store.commit('increment');// ❌ Pinia 没有 commit

修复:Pinia 直接改 state,actions 里直接操作

// ✅ Pinia:直接改,不需要 mutationsimport{defineStore}from'pinia';exportconstuseCounterStore=defineStore('counter',{state:()=>({count:0}),actions:{increment(){this.count++;// ✅ 直接改,不需要 commit},asyncIncrement(){this.count++;// ✅ action 里也可以直接改}}});// 组件里constcounter=useCounterStore();counter.increment();// ✅ 直接调counter.count=10;// ✅ 也可以直接改
② Vuex 模块嵌套太深,取数据一长串
// ❌ Vuex 模块嵌套:取数据路径太长conststore={modules:{user:{modules:{profile:{state:()=>({name:'张三'}),namespaced:true}}}}};// 组件里this.$store.state.user.profile.name;// ❌ 路径太长this.$store.commit('user/profile/setName','李四');// ❌ 命名空间拼接

修复:Pinia 每个 Store 独立,扁平化

// ✅ Pinia:每个 Store 独立定义exportconstuseUserStore=defineStore('user',()=>{constname=ref('张三');constsetName=(val)=>{name.value=val;};return{name,setName};});// 组件里直接用constuserStore=useUserStore();userStore.name;// ✅ 直接访问userStore.setName('李四');// ✅ 直接调用
③ 用 setup 语法时 Vuex 类型推断差
// ❌ Vuex + TypeScript:类型推断差,需要大量断言import{useStore}from'@/store';conststore=useStore();constcount=store.state.count;// ❌ 类型是 anyconstuser=store.state.user.nameasstring;// ❌ 手动断言

修复:Pinia 自动类型推断

// ✅ Pinia:自动类型推断import{useUserStore}from'@/stores/user';constuserStore=useUserStore();userStore.name;// ✅ 自动推断 stringuserStore.setName('李四');// ✅ 参数类型自动校验
// ✅ setup 风格的 Storeimport{defineStore}from'pinia';import{ref,computed}from'vue';exportconstuseUserStore=defineStore('user',()=>{constname=ref<string>('张三');constage=ref<number>(18);constinfo=computed(()=>`${name.value},${age.value}`);constsetName=(val:string)=>{name.value=val;};return{name,age,info,setName};});
④ Pinia 持久化:刷新后状态丢失
// ❌ Pinia 默认不持久化,刷新页面状态丢失exportconstuseUserStore=defineStore('user',()=>{consttoken=ref('');constlogin=(t)=>{token.value=t;};return{token,login};});// 刷新页面 → token 变回空字符串 ❌

修复方案一:手动 localStorage

// ✅ 在 action 里手动存exportconstuseUserStore=defineStore('user',()=>{consttoken=ref(localStorage.getItem('token')||'');constlogin=(t)=>{token.value=t;localStorage.setItem('token',t);// ✅ 存};constlogout=()=>{token.value='';localStorage.removeItem('token');// ✅ 清};return{token,login,logout};});

修复方案二:用 pinia-plugin-persistedstate 插件

// ✅ 插件自动持久化import{createPinia}from'pinia';importpiniaPluginPersistedstatefrom'pinia-plugin-persistedstate';constpinia=createPinia();pinia.use(piniaPluginPersistedstate);// ✅ 全局注册// Store 里声明 persistexportconstuseUserStore=defineStore('user',{state:()=>({token:'',user:null}),persist:true,// ✅ 自动持久化整个 state});
⑤ Pinia 解构丢失响应式
<!-- ❌ 解构后丢失响应式 --> <script setup> import { useUserStore } from '@/stores/user'; const userStore = useUserStore(); const { name, age } = userStore; // ❌ 解构后不是响应式的 </script> <template> <div>{{ name }}</div> <!-- ❌ name 变了页面不更新 --> </template>

修复:用 storeToRefs

<!-- ✅ 用 storeToRefs 解构,保持响应式 --> <script setup> import { storeToRefs } from 'pinia'; import { useUserStore } from '@/stores/user'; const userStore = useUserStore(); const { name, age } = storeToRefs(userStore); // ✅ 响应式保留 // actions 可以直接解构(函数不需要响应式) const { setName } = userStore; </script> <template> <div>{{ name }}</div> <!-- ✅ name 变了页面更新 --> </template>

三、万能兜底:Pinia 标准 Store 模板

Option 风格(类似 Vuex,适合简单 Store)

import{defineStore}from'pinia';exportconstuseCounterStore=defineStore('counter',{state:()=>({count:0,history:[],}),getters:{double:(state)=>state.count*2,historyLength:(state)=>state.history.length,},actions:{increment(){this.count++;this.history.push('+1');},decrement(){this.count--;this.history.push('-1');},reset(){this.count=0;this.history=[];},},});

Setup 风格(Composition API,推荐)

import{defineStore}from'pinia';import{ref,computed}from'vue';exportconstuseUserStore=defineStore('user',()=>{// stateconstuser=ref(null);consttoken=ref('');// gettersconstisLoggedIn=computed(()=>!!token.value);constuserName=computed(()=>user.value?.name||'游客');// actionsconstlogin=async(credentials)=>{constres=awaitfetch('/api/login',{method:'POST',body:JSON.stringify(credentials),});constdata=awaitres.json();token.value=data.token;user.value=data.user;};constlogout=()=>{token.value='';user.value=null;};constupdateUser=(patch)=>{user.value={...user.value,...patch};};return{// stateuser,token,// gettersisLoggedIn,userName,// actionslogin,logout,updateUser,};});

组件里使用

<script setup> import { storeToRefs } from 'pinia'; import { useUserStore } from '@/stores/user'; const userStore = useUserStore(); // ✅ 响应式数据用 storeToRefs const { user, token, isLoggedIn, userName } = storeToRefs(userStore); // ✅ actions 直接解构 const { login, logout, updateUser } = userStore; // ✅ 也可以直接用 $patch 批量更新 const updateProfile = () => { userStore.$patch({ user: { name: '新名字' } }); }; // ✅ $reset 重置(仅 Option 风格支持) const resetAll = () => userStore.$reset(); </script>

四、预防 checklist

  • 新项目直接用 Pinia,不要用 Vuex
  • Pinia没有 mutations,actions 里直接this.xxx = val修改 state
  • 每个 Store独立定义,不需要 modules 嵌套
  • 组件里解构 Store 数据必须用 storeToRefs,否则丢失响应式
  • actions/methods可以直接解构,函数不需要响应式
  • 持久化用 pinia-plugin-persistedstate插件,或手动 localStorage
  • 推荐用setup 风格定义 Store(Composition API,TS 支持更好)
  • 跨 Store 调用:在 action 里useOtherStore()即可
  • $patch批量更新比逐个赋值性能更好
  • $reset()只在 Option 风格 Store 中可用,setup 风格需手动实现

五、一句话总结

「Pinia = 更轻更直觉的 Vuex」。砍掉 mutations、扁平化 Store、setup 语法原生支持、TS 自动推断。新项目无脑 Pinia,解构用 storeToRefs,持久化用插件。状态管理就该这么简单!


最后问候亲爱的朋友们,并邀请你们阅读我的全新著作

📚 《Vue.js 3企业级项目开发实战(微课视频版》

http://www.jsqmd.com/news/1311497/

相关文章:

  • 2026 年新消息:安远靠谱的单向止水闸门供货厂家综合实力解析,暴雨天能反向顶死洪水的这玩意儿,藏在小区地下车库不起眼角落 - 品质体验官
  • 2026年泸州公务员报考咨询机构怎么选?本地化考情服务成关键考量因素 - 优质品牌商家
  • 从《英雄联盟》神秘之剑看高风险高回报装备的设计与平衡
  • 南阳交通事故伤残鉴定难怎么办?2026年这5位律师专业推荐 - 本地品牌推荐
  • 大模型演进风向:超长上下文与智能体能力如何重塑AI应用开发
  • 2026 年更新:柳州正规的负离子藻钙板实力厂家怎么联系,刷墙选这货能让家多30%负氧离子?难怪邻居都在问链接-天顺高晶板 - 企业官方推荐【认证】
  • HDMI电子纸驱动板设计:从方案选型到Linux驱动开发全解析
  • 嵌入式SD卡存储模块设计:从SPI/SDIO接口到FATFS文件系统实战
  • 6款AI论文网站汇总
  • 华为模拟器添加卡片
  • NVIDIA VPI:统一异构计算后端,构建高性能边缘视觉处理流水线
  • 2026 年新发布:宁德靠谱的耐候钢花箱供应厂家哪家专业,小区角落不起眼的这玩意儿,居然能扛住十年风霜还能当装饰? - 企业推荐官【认证官方】
  • Grove录音模块工程化应用:从ISD1820P原理到抗干扰设计实战
  • 抗衰的尽头是胶原
  • 工业通信RS232转RS485(D)转换器:原理、设计与实战调试
  • 在石家庄做全屋定制,真没几个好品牌,这几个算的上头部品牌
  • DockDoor:让macOS窗口管理像翻书一样自然
  • 2026 年宁德比较好的白酒加盟供应厂家哪家权威,别再跟风折腾了!这事居然比你卖奶茶还稳,藏着多少人没敢说的赚钱门道? - 实业推荐官【官方】
  • 银河麒麟V10系统安装配置JDK全攻略:从OpenJDK到环境变量避坑
  • GPT-5.4原生操控电脑:从环境感知到自动化执行的AI桌面革命
  • 持久化执行前置课(七):崩溃恢复不是重跑,而是先判定已知与未知
  • AI FaultLab:给 Hybrid RAG 补上检索评测闭环
  • 基于Jetson Orin与ESP32的AI机器人开发:从硬件选型到视觉跟踪实战
  • 微客外链功能解析:抖音_快手私信跳转微信的实现原理与技术路径
  • 2026 年当下,天河可靠的膜结构汽车棚电动车棚选哪家优质厂家哪家可靠,别再瞎花钱装车棚了?这款实用型靠谱方案竟能省出半台车钱 - 鉴选官
  • MP4转MP3全平台实战指南:原理、工具与音质优化
  • 2026夏天选旅行社看这篇:西藏旅行社推荐与投诉率大比拼,我们对比了20家,这份避坑名单请收好| 附:旅行社电话 - 西藏康泰旅行社
  • 2026 年当下,巴林右旗有实力的不锈钢洗手池工厂哪家强,用了十年才发现,这玩意儿比瓷砖省心10倍,看完赶紧换-丰卓不锈钢厨具设备 - 企业信息推荐【官方】
  • 【MiniMax H3技术解析】2K原生双声道、全模态控制与开源路线
  • Java 版本演进