uni-app小程序开发-使用Pinia进行全局状态管理

2024-07-24 13:56:25 浏览数 (2)

与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 中编写以下代码:

代码语言:javascript复制
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 = '全国';

0 人点赞