与VueX对比
Pinia (发音为 /piːnjʌ/)支持 Vue 3 和 Vue 2 ,对 TypeScript 也有很完好的支持,与 Vuex
相比,Pinia
提供了一个更简单的 API,提供了 Composition-API
风格的 API,最重要的是,在与 TypeScript 一起使用时具有可靠的类型推断支持。
状态管理弃用了 vuex 而采用Pinia 的 5个重要条件:
- Pinia 的 API 设计非常接近 Vuex 5 的提案。(作者是 Vue 核心团队成员)
- 无需像 Vuex 4 自定义复杂的类型来支持 typescript,天生具备完美的类型推断。
- 模块化设计,你引入的每一个 store 在打包时都可以自动拆分他们。
- 无嵌套结构,但你可以在任意的 store 之间交叉组合使用。
- Pinia 与 Vue devtools 挂钩,不会影响 Vue 3 开发体验。
Pinia API 与 Vuex ≤4 有很大不同,即:
mutations 不再存在
。他们经常被认为是非常冗长。他们最初带来了 devtools 集成,但这不再是问题。- 更好的TypeScript支持。无需创建自定义复杂包装器来支持 TypeScript,所有内容都是类型化的,并且 API 的设计方式尽可能利用 TS 类型推断。
- 不再需要注入、导入函数、调用函数、享受自动完成功能!
- 无需动态添加 Store,默认情况下它们都是动态的,您甚至都不会注意到。请注意,您仍然可以随时手 动使用 Store 进行注册,但因为它是自动的,您无需担心。
不再有 modules 的嵌套结构
。您仍然可以通过在另一个 Store 中导入和 使用 来隐式嵌套 Store,但 Pinia 通过设计提供平面结构,同时仍然支持 Store 之间的交叉组合方式。 您甚至可以拥有 Store 的循环依赖关系。没有命名空间模块
。鉴于 Store 的扁平架构,“命名空间” Store 是其定义方式所固有的,您可以说 所有 Store 都是命名空间的。
有关如何将现有 Vuex ≤4 项目转换为使用 Pinia 的更详细说明,请参阅 从Vuex 迁移指南。
状态树的结构
作用 | Vue Component | Vuex | Pinia |
---|---|---|---|
数据管理 | data | state | state |
数据计算 | computed | getters | getters |
行为方法 | methods | mutations / actions | actions |
可以看到 Pinia 的结构和用途都和 Vuex 与 Component 非常相似,并且 Pinia 相对于 Vuex ,在行为方法部分去掉了 mutations (同步操作)和 actions (异步操作)的区分
,更接近组件的结构,入门成本会更低一些。
uni-app中使用
https://uniapp.dcloud.net.cn/tutorial/vue3-pinia.html
注意
uni-app 内置了 Pinia 。Vue 2 项目暂不支持。 HBuilder X 已内置了 Pinia,无需手动安装。
项目结构
代码语言:javascript复制├── pages
├── static
└── stores
└── common.js
├── App.vue
├── main.js
├── manifest.json
├── pages.json
└── uni.scss
在 main.js
中编写以下代码:
import App from './App'
import { createSSRApp } from 'vue';
import * as Pinia from 'pinia';
export function createApp() {
const app = createSSRApp(App);
app.use(Pinia.createPinia());
return {
app,
Pinia, // 此处必须将 Pinia 返回
};
}
首先创建一个 Store:
代码语言:javascript复制import {
defineStore
} from 'pinia';
export const useCommonStore = defineStore('common', {
state: () => {
return {
count: 0,
cityName: "郑州"
};
},
actions: {
increment() {
this.count ;
},
},
});
使用
代码语言:javascript复制import { useCommonStore } from '@/stores/common';
import { mapState, mapStores, mapActions } from 'pinia'
export default {
computed: {
// 允许访问 this.commonStore
...mapStores(useCommonStore),
// 允许读取 this.count 和 this.cityName
...mapState(useCommonStore, ['count', 'cityName']),
},
methods: {
// 允许读取 this.increment()
...mapActions(useCommonStore, ['increment']),
},
}
赋值
代码语言:javascript复制this.commonStore.cityName = '全国';