diff --git a/docs/pinia.md b/docs/pinia.md new file mode 100644 index 0000000..5a7a35e --- /dev/null +++ b/docs/pinia.md @@ -0,0 +1,368 @@ +Pinia 备忘清单 +=== + +这是一份 [`Pinia`](https://pinia.vuejs.org/) 状态管理库的备忘单,列出了 Pinia 的常用命令和操作。 + +入门 +--- + +### 安装 Pinia + +```bash +npm install pinia +# or +yarn add pinia +# or +pnpm add pinia +``` + +### 创建 Pinia 实例 + +在你的 Vue 应用中创建一个 Pinia 实例并将其传递给 Vue: + +```javascript +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') +``` + +### 定义 Store + +创建一个 store 文件(例如 `src/stores/counter.js`),并定义 store: + +```javascript +import { defineStore } from 'pinia' + +export const useCounterStore = defineStore('counter', { + state: () => ({ + count: 0 + }), + actions: { + increment() { + this.count++ + } + }, + getters: { + doubleCount: (state) => state.count * 2 + } +}) +``` + +### 使用 Store + +在组件中使用 store: + +```javascript + + + +``` + +### 热重载 Store + +使用 Vite 时,你可以启用热重载功能: + +```javascript +if (import.meta.hot) { + import.meta.hot.accept(acceptHMRUpdate(useCounterStore, import.meta.hot)) +} +``` + +### Modules 模式 + +Pinia 不使用传统的 Vuex 模块模式。相反,推荐使用独立的 store 文件: + +```javascript +// 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: + +```javascript + +``` + +高级用法 +--- + +### 使用组合函数 + +你可以将 store 与组合函数一起使用: + +```javascript +// 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 的功能: + +```javascript +// 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) +``` + +### SSR 支持 + +Pinia 支持服务端渲染 (SSR)。在你的 SSR 入口文件中创建 Pinia 实例: + +```javascript +import { createPinia } from 'pinia' + +export function createApp() { + const app = createSSRApp(App) + const pinia = createPinia() + + app.use(pinia) + return { app, pinia } +} +``` + +明白了,让我们来结合 `pinia-plugin-persist` 插件完善 Pinia 备忘清单。 + +### 持久化状态 + +#### 1. 安装 `pinia-plugin-persist` + +```bash +npm pinia-plugin-persist +``` + +#### 2. 配置 Pinia 和 `pinia-plugin-persist` + +在你的入口文件中配置 Pinia 和 `pinia-plugin-persist`。 + +**Vue 2 项目:** + +```javascript +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 项目:** + +```javascript +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,并启用持久化存储。 + +```javascript +// 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。 + +```javascript +// src/components/SomeComponent.vue + + + +``` + + +### 使用 Vue Devtools + +Pinia 可以与 Vue Devtools 一起使用。确保你安装了最新版本的 Vue Devtools,然后你可以在 Devtools 中查看和调试你的 Pinia store。 + +### 使用异步 Actions + +Pinia 支持在 actions 中使用异步代码: + +```javascript +// 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: + +```javascript +// __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) + }) +}) +``` + +另见 +--- + +- [Pinia 官方文档](https://pinia.vuejs.org/) +- [Pinia GitHub 仓库](https://github.com/vuejs/pinia) +- [Pinia 快速上手](https://pinia.vuejs.org/getting-started.html) +- [pinia-plugin-persist 官方文档](https://seb-l.github.io/pinia-plugin-persist/basic-usage.html)