一、Pinia 的介绍与作用
Pinia 是 Vue 官方最新推荐的、取代传统 Vuex 的一款工具,可以理解为 Vuex 的进阶版,它有几点好处:
1、数据结构更简单,简化 Vuex 声明繁琐的 module 嵌套结构带来的问题,一切都是扁平式的。
2、更好用、简洁明了的语法糖,就像 Vue3 Steup 那样,更新数据直接赋值,不再像 Vuex 那样要经过几个步骤。
3、更友好的兼容、支持 TypeScript 类型推导,不再像 Vuex 那样手动定义一套复杂的 TS 。
二、Pinia 安装&引入
2.1 安装依赖
npm i pinia
or
yarn add pinia
2.2 引入依赖
import { createApp } from 'vue'
import App from './App.vue'
import { createPinia } from 'pinia' // ++
const pinia = createPinia() // ++
const app = createApp(App) // ++
app.use(pinia) // ++
.mount('#app')
三、使用方式1
3.1 声明定义
随意建个文件并以 use 开头作为文件名,例如:useCounter.js,示例代码如下:
useXXX 仅作为一种声明规范,看你心情定义。
// src/store/useCounter.js
import { defineStore } from 'pinia'
export const userCounter = defineStore('counter', {
state: () => ({
count: 0,
}),
getters: {
doubleCount: (state) => state.count * 2,
},
actions: {
increment() {
this.count ++
}
}
})
白话参数解释:
state当作声明 Vue2dataor Vue3ref/reative里的响应式数据。getters当作 Vue2/3 里的computed属性。actions当作 Vue2/3 定义methods函数。
3.2 视图渲染
<script>
import { userCounter } from './store/useCounter'
export default {
setup() {
const counter = userCounter()
return {
counter,
}
},
}
</script>
<template>
<button @click="counter.increment()">Increase</button>
<div>
Count: {{ counter.count }}
</div>
</template>

四、使用方式2
4.1 声明定义
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
export const userCounter = defineStore('counter', () => {
const count = ref(0)
const increment = () => {
count.value ++
}
const doubleCount = computed(() => count.value * 2)
return {
count,
increment,
doubleCount,
}
})`
白话参数解释:
上面这些代码你没看错,根据使用方式1我们知道 state 形如 data 或 ref ,因此我们可以 Vue3 提供的语法来声明、获取、赋值,
Pinia 能够让我们写 store 代码就像写 Vue3 代码一样简单。
4.2 视图渲染
效果和上面一样,代码完全不用变!!!
五、高级语法糖
5.1 store.$patch
定义:store.$patch() 允许你一次性直接更新多个 state 变量。
用法1:基本类型操作
import { userCounter } from './store/useCounter'
const counter = userCounter()
const patch = () => {
counter.$patch({
count: counter.count + 1,
// 假设 counter 还声明了 age, name 变量:
age: 120,
name: 'DIO',
})
}
return {
patch,
counter,
}
<button @click="patch()">Patch</button>
<div>
Count: {{ counter.count }}
</div>
同时更新 count, age, name 。

用法2:引用类型操作(增删改)
counter .$patch((state) => {
counter.aaaa.push({ name: 'shoes', quantity: 1 })
counter.bbbb = true
})
通过一个回调函数传 state 的方式来改变引用对象,效果图就不展示了,和上面一样实时更新。
熟悉 React useState 语法的都知道,以上两种用法正好对应 React 的 setState ,唯一不同的是,$patch 里直接操作 state,而不用 return 。
5.2 Plugin
Pinia 允许你在引入 pinia 依赖时,通过注册一些插件的形式,向 store 注入一个全局对象或方法(响应式的),便于其它 state 直接引入使用,也可以直接注入其它第三方插件对象,比如 router, antd message 等。
代码示例如下:
// app.js
import { createPinia } from 'pinia'
function MyPiniaPlugin() {
return {
getPluginName: 'Hello, I am a plugin.',
changePluginName() {
this.getPluginName = 'Jack'
}
}
}
const pinia = createPinia()
pinia.use(MyPiniaPlugin)
// App.vue
<script>
import { userCounter } from './store/useCounter'
export default {
setup() {
const counter = userCounter()
return {
counter,
}
},
}
</script>
<template>
<button @click="counter.changePluginName()">Change plugin name</button>
<div>
PluginName: {{ counter.getPluginName }}
</div>
</template>

六、事项与小技巧
- 对于【使用方式1】的语法来说,可直接使用 $reset() 来重置数据。
userCounter.$reset()

-
对于【使用方式2】的语法来说,Vue3 的任何 API 语法都可以在 defineStore 里直接引用。
-
defineStore('alerts', ....}第一个参数名字必须是唯一的,是后续访问该 state 的唯一标识符。
七、结语
- Pinia 能够让我们写 Store 就像写平时的 Vue2 data 和 Vue3 setup 一样简单。
- Pinia 支持多种写法来声明 Store ,简单且灵活,释放我们的小双手。
- 以上内容便是 Pinia 中比较常见的用法,我认为够用了,对其它语法感兴趣的可查阅文档。
完!
1318

被折叠的 条评论
为什么被折叠?



