这是一份 Pinia
状态管理库的备忘单,列出了 Pinia 的常用命令和操作。
npm install pinia# oryarn add pinia# orpnpm add pinia
创建一个 store 文件(例如 src/stores/counter.js
),并定义 store
import { defineStore } from 'pinia'export const useCounterStore = defineStore('counter', {state: () => ({count: 0}),actions: {increment() {this.count++}},getters: {doubleCount: (state) => state.count * 2}})
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
使用 Vite 时,你可以启用热重载功能:
if (import.meta.hot) {import.meta.hot.accept(acceptHMRUpdate(useCounterStore, import.meta.hot))}
在组件中使用 store
<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>
Pinia 不使用传统的 Vuex 模块模式。相反,推荐使用独立的 store 文件:
// src/stores/user.jsimport { 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,可以这样使用 Pinia:
<script>import { defineComponent } from 'vue'import { useCounterStore } from '@/stores/counter'export default defineComponent({setup() {const counterStore = useCounterStore()return {counterStore}}})</script>
你可以将 store 与组合函数一起使用:
// src/composables/useCounter.jsimport { useCounterStore } from '@/stores/counter'export function useCounter() {const counterStore = useCounterStore()return {count: counterStore.count,doubleCount: counterStore.doubleCount,increment: counterStore.increment}}
Pinia 支持插件。你可以编写插件来扩展 Pinia 的功能:
// src/plugins/piniaPlugin.jsexport function piniaPlugin({ store }) {store.$onAction(({ name, store, args, after, onError }) => {console.log(`Action ${name} was called with args:`, args)})}// main.jsimport { createPinia } from 'pinia'import { piniaPlugin } from './plugins/piniaPlugin'const pinia = createPinia()pinia.use(piniaPlugin)
pinia-plugin-persist
npm pinia-plugin-persist
pinia-plugin-persist
在你的入口文件中配置 Pinia 和 pinia-plugin-persist
。
⚠️ Vue 2 项目
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 项目:
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')
创建一个 Pinia store,并启用持久化存储。
// stores/userStore.jsimport { 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']}]}})
在组件中使用创建好的 store。
// 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>
Pinia 支持服务端渲染 (SSR)。在你的 SSR 入口文件中创建 Pinia 实例:
import { createPinia } from 'pinia'export function createApp() {const app = createSSRApp(App)const pinia = createPinia()app.use(pinia)return { app, pinia }}
明白了,让我们来结合 pinia-plugin-persist
插件完善 Pinia 备忘清单。
Pinia 可以与 Vue Devtools 一起使用。确保你安装了最新版本的 Vue Devtools,然后你可以在 Devtools 中查看和调试你的 Pinia store。
Pinia 支持在 actions 中使用异步代码:
// src/stores/todo.jsimport { 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}}})
你可以使用 Vue Test Utils 和 Jest 来测试你的 Pinia store:
// __tests__/counterStore.test.jsimport { 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 = 2expect(counterStore.doubleCount).toBe(4)})})