1、pinia简介
Pinia(发音为 /piːnjʌ/,类似于英语中的“peenya”)是最接近有效包名 piña(西班牙语中的_pineapple_)的词。
Pinia 是由 Vue.js 团队成员开发,新一代的状态管理器,即 Vuex5.x。
特点:
-
对 Vue 2 和 Vue 3 都有效
-
完整的 typescript 的支持
-
只有 state, getter 和 action ,去掉了mutations,简化状态管理库
-
actions 支持同步和异步方法修改 state 状态
-
不再有模块嵌套,只有 Store 的概念,Store 之间可以相互调用
-
足够轻量,压缩后的体积只有1.6kb
-
使用插件扩展 Pinia 功能
2、使用方式
安装
npm install pinia
创建 Store
新建 src/store 目录并在其下面创建 index.js,导出 store
import { createPinia } from 'pinia'
const store = createPinia()
export default store
在 main.js 中引入并使用
import { createApp } from 'vue'
import App from './App.vue'
import store from './store'
const app = createApp(App)
app.use(store)
app.mount('#app')
3、State
store 的核心部分。 我们通常从定义应用程序的状态开始。 在 Pinia 中,状态被定义为返回初始状态的函数。 Pinia 在服务器端和客户端都可以工作。
定义state
import { defineStore } from 'pinia'
export const useUserStore = defineStore({
id: 'user', // id必填,且需要唯一
state: () => {
return {
name: '牛牛'
}
}
})
获取state
import {useUserStore} from "@/store/user";
const userStore = useUserStore()
const name = computed(() => userStore.name)
修改state
(1) 直接修改
userStore.name = '芳芳'
优点:最简单直接的修改方法,代码少。
缺点:只能一次修改一个,不能修改多个。全局的状态管理还是不要直接在各个组件处随意修改状态,应放于 action 中统一方法修改
(2)通过storeToRefs转为ref后修改
const {name} = storeToRefs(userStore)
name.value = '芳芳'
不使用storeToRefs 直接解构会失去响应式,导致修改失败
优点:可以解构store中的内容,代码也不多。
缺点:不能一次修改多个,而且还需要引入storeToRefs,比第一种方法多了一点代码。
(3)$patch
可传对象或函数
userStore.$patch({
name: '芳芳'
})
// 不能直接修改原来的state,对state中的数组或对象不能增加或删除,只能创建新的对象进行赋值。
userStore.$patch(state=>{
state.name='芳芳'
})
// 可以一次修改多个,可以修改原来的state,对state中的数组或对象可以使用方法修改
(4)action
action 里可以直接通过 this 访问
// store中
import { defineStore } from 'pinia'
export const useUserStore = defineStore({
id: 'user', // id必填,且需要唯一
state: () => {
return {
name: '牛牛'
}
},
actions: {
updateName(name) {
this.name = name
}
}
})
// 具体使用
userStore.updateName('芳芳')
重置state
const reset = () => {
userStore.$reset()
}
4、Getters
等同于 Store 状态的计算值
getters: {
fullName1: (state) => {
return state.name = state.name + '放大镜'
},
fullName2 () {
return this.name = '芳芳放大镜'
}
},
5、Action
相当于组件中的 methods,适合定义业务逻辑
-
action 可以像写一个简单的函数一样支持 async/await 的语法,让你愉快的应付异步处理的场景。
-
action 间的相互调用,直接用 this 访问即可。
-
在 action 里调用其他 store 里的 action 也比较简单,引入对应的 store 后即可访问其内部的方法了。
changePwd(value) {
const pwdStore = usePwdStore()
pwdStore.changePwd(value)
this.pwd = pwdStore.getPwd
}
6、Plugins
由于是底层 API,Pania Store 完全支持扩展。以下是可以扩展的功能列表:
-
向 Store 添加新状态
-
定义 Store 时添加新选项
-
为 Store 添加新方法
-
包装现有方法
-
更改甚至取消操作
-
实现本地存储等副作用
-
仅适用于特定 Store
Pinia 插件是一个函数,接受一个可选参数 context ,context 包含四个属性:app 实例、pinia 实例、当前 store 和选项对象。
函数也可以返回一个对象,对象的属性和方法会分别添加到 state 和 actions 中。
export function myPiniaPlugin(context) {
context.app // 使用 createApp() 创建的 app 实例(仅限 Vue 3)
context.pinia // 使用 createPinia() 创建的 pinia
context.store // 插件正在扩展的 store
context.options // 传入 defineStore() 的选项对象(第二个参数)
// ...
return {
hello: 'world', // 为 state 添加一个 hello 状态
changeHello() { // 为 actions 添加一个 changeHello 方法
this.hello = 'pinia'
}
}
}
然后使用 store.use() 将此函数传递给 pinia 就可以了
这对于添加全局对象(如路由器\ toast 管理器)很有用。
还可以在定义 store 时创建新选项,以便以后从插件中使用它们。
例如,您可以创建一个 debounce 选项,允许您对任何操作进行去抖动:
defineStore('search', {
actions: {
searchContacts() {
// ...
},
},
// 稍后将由插件读取
debounce: {
// 将动作 searchContacts 防抖 300ms
searchContacts: 300,
},
})
然后插件可以读取该选项以包装操作并替换原始操作:
if (context.options.debounce) {
// 我们正在用新的action覆盖这些action
return Object.keys(context.options.debounce).reduce((debouncedActions, action) => {
debouncedActions[action] = debounce(
context.store[action],
context.options.debounce[action]
)
return debouncedActions
}, {})
}
7、vuex
在 Vuex store(仓库)中,有4个主要组件。
1. State
这只是一个包含实际状态的对象。我们可以在开发工具中看到这个状态,如果想保留这个状态用于缓存或其他目的,也可以保存这个对象。
2. Actions
Actions 是执行异步任务的函数。它们是由关键字dispatch发起的。
Actions 通常会请求一个外部 API 或做一些其他的异步工作。它还负责调用适当的 mutation 来实际改变状态。这说明 actions 本身并没有改变状态,而是 commit 变化,让 mutation 来改变状态。
3. Mutations
Mutation 是唯一会真正同步改变状态的函数。Mutations 使用关键字commit。
4. Getters
Getters可以被认为是计算过的属性,应该被用来从状态中获得一个修改过的响应。
const store = createStore({
state: {
count: 0
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
increment (context) {
context.commit('increment')
}
}
})
8、总结
Pinia 整体来说比 Vuex 更加简单、轻量,但功能却更加强大,也许这就是它取代 Vuex 的原因吧~
参考文档
介绍 | Pinia 中文文档
大菠萝?Pinia已经来了,再不学你就out了 - 掘金
还有人没尝过 Pinia 吗,请收下这份食用指南! - 掘金
测试一下Pinia,Vuex 要出局了?_测试pinia-CSDN博客
28 vue3 Pinia修改state的三种方法(直接修改,$patch,actions)-CSDN博客
Pinia修改State的四种方式_pinia修改state数据-CSDN博客