这是一份 Pinia 状态管理库的备忘单,列出了 Pinia 的常用命令和操作。

入门

安装 Pinia

1
2
3
4
5
npm install pinia
# or
yarn add pinia
# or
pnpm add pinia

定义 Store

创建一个 store 文件(例如 src/stores/counter.js),并定义 store

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0
}),
actions: {
increment() {
this.count++
}
},
getters: {
doubleCount: (state) => state.count * 2
}
})

创建 Pinia 实例

1
2
3
4
5
6
7
8
9
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'

const app = createApp(App)
const pinia = createPinia()

app.use(pinia)
app.mount('#app')

在你的 Vue 应用中创建一个 Pinia 实例并将其传递给 Vue

热重载 Store

使用 Vite 时,你可以启用热重载功能:

1
2
3
if (import.meta.hot) {
import.meta.hot.accept(acceptHMRUpdate(useCounterStore, import.meta.hot))
}

使用 Store

在组件中使用 store

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<template>
<div>
<p>Count: {{ counterStore.count }}</p>
<p>Double Count: {{ counterStore.doubleCount }}</p>
<button @click="counterStore.increment">Increment</button>
</div>
</template>

<script>
import { useCounterStore } from '@/stores/counter'

export default {
setup() {
const counterStore = useCounterStore()

return {
counterStore
}
}
}
</script>

Modules 模式

Pinia 不使用传统的 Vuex 模块模式。相反,推荐使用独立的 store 文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// src/stores/user.js
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
state: () => ({
name: 'Alice',
age: 25
}),
actions: {
setName(name) {
this.name = name
}
},
getters: {
isAdult: (state) => state.age >= 18
}
})

使用 Options API

如果你更喜欢 Options API,可以这样使用 Pinia:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<script>
import { defineComponent } from 'vue'
import { useCounterStore } from '@/stores/counter'

export default defineComponent({
setup() {
const counterStore = useCounterStore()

return {
counterStore
}
}
})
</script>

高级用法

使用组合函数

你可以将 store 与组合函数一起使用:

1
2
3
4
5
6
7
8
9
10
11
12
// src/composables/useCounter.js
import { useCounterStore } from '@/stores/counter'

export function useCounter() {
const counterStore = useCounterStore()

return {
count: counterStore.count,
doubleCount: counterStore.doubleCount,
increment: counterStore.increment
}
}

插件

Pinia 支持插件。你可以编写插件来扩展 Pinia 的功能:

1
2
3
4
5
6
7
8
9
10
11
12
13
// src/plugins/piniaPlugin.js
export function piniaPlugin({ store }) {
store.$onAction(({ name, store, args, after, onError }) => {
console.log(`Action ${name} was called with args:`, args)
})
}

// main.js
import { createPinia } from 'pinia'
import { piniaPlugin } from './plugins/piniaPlugin'

const pinia = createPinia()
pinia.use(piniaPlugin)

持久化状态

1. 安装 pinia-plugin-persist

1
npm  pinia-plugin-persist

2. 配置 Pinia 和 pinia-plugin-persist

在你的入口文件中配置 Pinia 和 pinia-plugin-persist

⚠️ Vue 2 项目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import Vue from 'vue'
import vueCompositionApi from '@vue/composition-api'
import { createPinia, PiniaVuePlugin } from 'pinia'
import piniaPersist from 'pinia-plugin-persist'
import App from './App.vue'

Vue.use(vueCompositionApi)
Vue.use(PiniaVuePlugin)

const pinia = createPinia()
pinia.use(piniaPersist)

new Vue({
pinia,
render: h => h(App)
}).$mount('#app')

Vue 3 项目:

1
2
3
4
5
6
7
8
9
10
11
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import piniaPersist from 'pinia-plugin-persist'
import App from './App.vue'

const pinia = createPinia()
pinia.use(piniaPersist)

createApp(App)
.use(pinia)
.mount('#app')

3. 创建 Store 并启用持久化

创建一个 Pinia store,并启用持久化存储。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// stores/userStore.js
import { defineStore } from 'pinia'

export const useUserStore = defineStore('userStore', {
state: () => ({
firstName: 'S',
lastName: 'L',
accessToken: 'xxxxxxxxxxxxx'
}),
actions: {
setToken(value) {
this.accessToken = value
}
},
persist: {
enabled: true,
strategies: [
{
storage: localStorage,
paths: ['accessToken']
}
]
}
})

4. 使用 Store

在组件中使用创建好的 store。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// src/components/SomeComponent.vue
<template>
<div>
<p>{{ userStore.firstName }} {{ userStore.lastName }}</p>
<p>{{ userStore.accessToken }}</p>
</div>
</template>

<script>
import { useUserStore } from '@/stores/userStore'

export default {
setup() {
const userStore = useUserStore()

return { userStore }
}
}
</script>

SSR 支持

Pinia 支持服务端渲染 (SSR)。在你的 SSR 入口文件中创建 Pinia 实例:

1
2
3
4
5
6
7
8
9
import { createPinia } from 'pinia'

export function createApp() {
const app = createSSRApp(App)
const pinia = createPinia()

app.use(pinia)
return { app, pinia }
}

明白了,让我们来结合 pinia-plugin-persist 插件完善 Pinia 备忘清单。

使用 Vue Devtools

Pinia 可以与 Vue Devtools 一起使用。确保你安装了最新版本的 Vue Devtools,然后你可以在 Devtools 中查看和调试你的 Pinia store。

使用异步 Actions

Pinia 支持在 actions 中使用异步代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// src/stores/todo.js
import { defineStore } from 'pinia'
import axios from 'axios'

export const useTodoStore = defineStore('todo', {
state: () => ({
todos: []
}),
actions: {
async fetchTodos() {
const response = await axios.get('/api/todos')
this.todos = response.data
}
}
})

测试 Pinia Store

你可以使用 Vue Test Utils 和 Jest 来测试你的 Pinia store:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// __tests__/counterStore.test.js
import { setActivePinia, createPinia } from 'pinia'
import { useCounterStore } from '@/stores/counter'

describe('Counter Store', () => {
beforeEach(() => {
setActivePinia(createPinia())
})

it('increments the count', () => {
const counterStore = useCounterStore()
expect(counterStore.count).toBe(0)
counterStore.increment()
expect(counterStore.count).toBe(1)
})

it('returns double count', () => {
const counterStore = useCounterStore()
counterStore.count = 2
expect(counterStore.doubleCount).toBe(4)
})
})

另见


评论
avatar
竹山一叶
技术分享 个人心得
Follow Me
公告
欢迎光临小站,这里是我日常工作和学习中收集和整理的总结,希望能对你有所帮助:)

本站的内容经过个人加工总结而来,也参考了网友们分享的资料,如有侵权,请第一时间联系我,我将及时进行修改或删除😊
文章归档文章分类文章标签复制本文标题复制本文地址
随便逛逛