diff --git a/docs/tutorial/_sidebar.md b/docs/tutorial/_sidebar.md index e1dc976a08962e698416d8cace373f1faa834d4c..027c2fb534e4ecac90e95955f7697d1599b37ca3 100644 --- a/docs/tutorial/_sidebar.md +++ b/docs/tutorial/_sidebar.md @@ -20,6 +20,7 @@ * [组件](/tutorial/vue3-components.md) * [API](/tutorial/vue3-api.md) * [vuex](/tutorial/vue3-vuex.md) + * [pinia](/tutorial/vue3-pinia.md) * [vue2 升 3 指南](/tutorial/migration-to-vue3.md) * [ts/typescript 专题](/tutorial/typescript-subject.md) * 编译器(条件编译) diff --git a/docs/tutorial/vue3-pinia.md b/docs/tutorial/vue3-pinia.md new file mode 100644 index 0000000000000000000000000000000000000000..e9c60c9cb20e2f2f2ebf9f613fec4865c240c05f --- /dev/null +++ b/docs/tutorial/vue3-pinia.md @@ -0,0 +1,140 @@ +# 状态管理 Pinia + +## 介绍 + +> uni-app 内置了 [Pinia](https://pinia.vuejs.org/) 。 + +### Pinia 是什么? + +Pinia(发音为 `/piːnjʌ/`,如英语中的 `peenya`) 是 Vue 的存储库,它允许您跨组件、页面共享状态。在服务器端以及小型单页应用程序中,您也可以从使用 Pinia 中获得很多好处: + +- 开发工具支持 + - 跟踪动作、突变的时间表 + - 存储出现在使用它们的组件中 + - 时间旅行和更容易的调试 +- 热模块更换 + - 修改您的存储而不重载您的页面 + - 在开发过程中保持任何现有状态 +- 为 JS 用户提供适当的 TypeScript 支持或自动完成功能 +- 插件: 通过插件扩展 Pinia 功能 +- 服务器端渲染支持 + +### 项目结构 + +``` +├── pages +├── static +└── stores + ├── counter.js +├── App.vue +├── main.js +├── manifest.json +├── pages.json +└── uni.scss +``` + +### 基本示例 + +在 `main.js` 中编写以下代码: + +```js +import { createSSRApp } from 'vue'; +import * as Pinia from 'pinia'; + +export function createApp() { + const app = createSSRApp(App); + app.use(Pinia.createPinia()); + return { + app, + Pinia, + }; +} +``` + +首先创建一个商店: + +```js +// stores/counter.js +import { defineStore } from 'pinia'; + +export const useCounterStore = defineStore('counter', { + state: () => { + return { count: 0 }; + }, + // 也可以这样定义 + // state: () => ({ count: 0 }) + actions: { + increment() { + this.count++; + }, + }, +}); +``` + +然后在组件中使用它: + +```js +import { useCounterStore } from '@/stores/counter'; + +export default { + setup() { + const counter = useCounterStore(); + + counter.count++; + // 可以手动触发 + counter.$patch({ count: counter.count + 1 }); + // 或者使用 actions + counter.increment(); + }, +}; +``` + +你甚至可以使用一个函数(类似于一个组件 setup())来为更高级的用例定义一个 Store: + +```js +export const useCounterStore = defineStore('counter', () => { + const count = ref(0); + function increment() { + count.value++; + } + + return { count, increment }; +}); +``` + +如果您仍然不熟悉 `setup() Composition API`,请不要担心,Pinia 还支持一组类似 Vuex 的 `map helpers`。 + +您以相同的方式定义存储,然后使用 `mapStores()` 、 `mapState()` 或 `mapActions()` 访问: + +```js +const useCounterStore = defineStore('counter', { + state: () => ({ count: 0 }), + getters: { + double: (state) => state.count * 2, + }, + actions: { + increment() { + this.count++ + } + } +}) + +const useUserStore = defineStore('user', { + // ... +}) + +export default { + computed: { + // 其他的计算属性 + // ... + // 通过 this.counterStore 和 this.userStore 访问 + ...mapStores(useCounterStore, useUserStore) + // 通过 this.count 和 this.double 访问 + ...mapState(useCounterStore, ['count', 'double']), + }, + methods: { + // 通过 this.increment() 访问 + ...mapActions(useCounterStore, ['increment']), + }, +} +```