vue3-pinia.md 3.1 KB
Newer Older
D
DCloud_LXH 已提交
1 2 3 4 5 6
# 状态管理 Pinia

## 介绍

> uni-app 内置了 [Pinia](https://pinia.vuejs.org/) 。

D
DCloud_LXH 已提交
7 8
> 使用 `HBuilder X` 不需要手动安装,直接使用即可。使用 `CLI` 需要手动安装,执行 `yarn add pinia` 或 `npm install pinia`。

D
DCloud_LXH 已提交
9 10
> Vue 2 项目暂不支持

D
DCloud_LXH 已提交
11 12 13 14 15 16 17 18 19 20 21 22 23
### Pinia 是什么?

Pinia(发音为 `/piːnjʌ/`,如英语中的 `peenya`) 是 Vue 的存储库,它允许您跨组件、页面共享状态。在服务器端以及小型单页应用程序中,您也可以从使用 Pinia 中获得很多好处:

- 开发工具支持
  - 跟踪动作、突变的时间表
  - 存储出现在使用它们的组件中
  - 时间旅行和更容易的调试
- 热模块更换
  - 修改您的存储而不重载您的页面
  - 在开发过程中保持任何现有状态
- 为 JS 用户提供适当的 TypeScript 支持或自动完成功能

D
DCloud_LXH 已提交
24
## 项目结构
D
DCloud_LXH 已提交
25 26 27 28 29

```
├── pages
├── static
└── stores
D
DCloud_LXH 已提交
30
    └── counter.js
D
DCloud_LXH 已提交
31 32 33 34 35 36 37
├── App.vue
├── main.js
├── manifest.json
├── pages.json
└── uni.scss
```

D
DCloud_LXH 已提交
38
## 基本示例
D
DCloud_LXH 已提交
39 40 41 42 43 44 45 46 47 48 49 50

`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,
D
DCloud_LXH 已提交
51
		Pinia, // 此处必须将 Pinia 返回
D
DCloud_LXH 已提交
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142
	};
}
```

首先创建一个商店:

```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']),
  },
}
```