自2024年以来,Pinia 已是 Vue.js 的官方首要推荐的状态管理库(即Vuex 的替代品)。
Pinia与Vuex4的npm下载趋势对比:
Pinia:每周 200万+ 下载量(快速增长)
Vuex4:每周 150万+ 下载量(缓慢下降)
1、为什么 Pinia "赢了"?
Vuex 的问题
- 复杂的 mutations/actions 分离
- 繁琐的模块配置
- TypeScript 支持差
- API 不够直观
Pinia的技术优势
- ✅ 更简单的 API(无 mutations)
- ✅ 更好的 TypeScript 支持
- ✅ 更小的体积(~1KB vs ~4KB)
- ✅ Composition API 风格
- ✅ 自动模块化
- ✅ 更友好的 DevTools
1.2、社区反馈
开发者调查(2024):
- 更喜欢 Pinia:78%
- 更喜欢 Vuex:12%
- 无所谓:10%
主要原因:
- "Pinia 写起来更舒服"
- "TypeScript 支持完美"
- "迁移到 Pinia 后代码更简洁"
- "学习曲线更低"
2、Pinia 使用
2.1. 安装 Pinia
npm install pinia
# 或
yarn add pinia
# 或
pnpm add pinia
2.2. 基本配置
main.js / main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
app.mount('#app')
2.3. 创建 Store
stores/demo.js / demo.ts
import { defineStore } from 'pinia'
export const useDemoStore = defineStore('demo', {
state: () => ({
// 值类型(基本类型)
count: 0,
name: '张三',
isActive: false,
price: 99.99,
// 引用类型(对象、数组)
user: {
id: 1,
name: '李四',
age: 25
},
items: ['苹果', '香蕉', '橙子'],
settings: {
theme: 'light',
language: 'zh-CN'
}
}),
actions: {
// 修改状态的方法
updateValue() {
// 可以直接修改
this.count = 100
this.name = '哈哈'
}
}
})
2.4. 值类型数据存取参考案例
存取数值、字符串、布尔值
<template>
<div>
<p>计数:{{ count }}</p>
<p>姓名:{{ name }}</p>
<p>是否激活:{{ isActive }}</p>
<button @click="changeValues">修改值类型</button>
</div>
</template>
<script setup>
import { useDemoStore } from '@/stores/demo'
const store = useDemoStore()
// 1. 直接读取(推荐)
console.log(store.count) // 0
console.log(store.name) // '张三'
console.log(store.isActive) // false
// 2. 直接修改(最简单方式)
function changeValues() {
// 直接赋值修改
store.count = 100 // 数字
store.name = '李四' // 字符串
store.isActive = true // 布尔值
store.price = 199.99 // 浮点数
// 自增自减
store.count++ // 101
store.count += 10 // 111
// 逻辑运算
store.isActive = !store.isActive // 取反
}
</script>
2.5. 引用类型存取参考案例
对象存取
<template>
<div>
<p>用户ID:{{ store.user.id }}</p>
<p>用户名:{{ store.user.name }}</p>
</div>
</template>
<script setup>
import { useDemoStore } from '@/stores/demo'
const store = useDemoStore()
// 1. 读取对象属性
console.log(store.user.id) // 1
console.log(store.user.name) // '李四'
// 2. 修改对象属性(直接修改)
function updateObject() {
// 方法1:直接修改属性(推荐)
store.user.name = '王五'
store.user.age = 30
// 方法2:替换整个对象
store.user = {
id: 2,
name: '赵六',
age: 28
}
// 方法3:使用展开运算符(保持其他属性)
store.user = {
...store.user, // 保留原有属性
name: '新名字', // 修改name
email: 'new@example.com' // 添加新属性
}
}
</script>