Pinia官网
📝 Pinia状态管理
1️⃣ 安装pinia
使用 npm 安装 Pinia:
npm install pinia
使用 yarn 安装 Pinia:
yarn add pinia
或者使用 yarn 安装 Pinia:安装之后在项目的配置文件package.json中会有pinia的依赖项,如图:
2️⃣ 将pinia引入项目,正常使用
首先在src文件夹下,创建store文件夹,index.ts子文件中创建pinia实例,如图:
index.ts代码展示:
//创建大仓库
import { createPinia } from 'pinia';
//createPinia方法可以用于创建大仓库
let store = createPinia();
//对外暴露,安装仓库
export default store;
最后在main.ts项目入口文件中引入创建的pinia就可以实现在项目中使用pinia进行数据的状态管理,以下是main.ts的代码实例:
// 引入实例化上下文的api方法createApp
import { createApp } from "vue";
// 引入App组件
import App from "./App.vue";
//引入仓库
import store from "./store";
// 创建app
const app = createApp(App);
app.use(store);
// 挂载
app.mount("#app");
3️⃣ pinia模块化
模块化特点
- Store(仓库):在 Pinia 中,Store 是定义和管理应用程序状态的地方。每个 Store 表示应用程序状态的一个模块或部分。您可以创建多个 Store,每个 Store 处理不同的关注点或数据段。
- 响应性:Pinia 利用了 Vue.js 的响应式系统,这意味着在 Pinia Store 内对状态进行的任何更改都会自动实现响应式。这种响应性允许组件根据 Store 状态的更改而自动更新,无需显式触发更新。
- 模块化方法:Pinia 鼓励采用模块化结构来组织 Store。每个 Store 是一个自包含的模块,封装了其状态和相关逻辑。这种模块化方法有助于保持关注点的清晰分离,并支持代码库的更好扩展性和可维护性。
- 可组合性:Pinia 中的 Store 可以相互组合。这意味着您可以在一个 Store 中访问和使用另一个 Store 中的状态或操作。这个特性促进了代码重用,并通过将简单的 Store 组合在一起来构建更复杂的状态管理结构。
- 使用 Vue 组合式 API:Pinia 设计用于与 Vue 组合式 API 无缝集成。它利用组合式 API 的响应能力,允许开发人员使用
ref
、computed
和reactive
等 Composition API 函数来定义 Store。
模块化示例:
在store中创建 modules 文件夹,这个文件夹下就是各个模块的文件所再位置,以info.ts文件为例就是创建一个仓库的方法,包括 state 数据定义, actions 数据的操作动作以修改数据, getters 用来获取数据,也可以进行简单的数据计算,
//定义info小仓库
import { defineStore } from "pinia";
//第一个仓库:小仓库名字 第二个参数:小仓库配置对象
//defineStore方法执行会返回一个函数,函数作用就是让组件可以获取到仓库数据
let useInfoStore = defineStore("info", {
//存储数据:state
state: () => {
return {
count: 99,
arr: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
}
},
actions: {
//注意:函数没有context上下文对象
//没有commit、没有mutations去修改数据
updateNum(a: number, b: number) {
this.count += a;
}
},
getters: {
total() {
let result:any = this.arr.reduce((prev: number, next: number) => {
return prev + next;
}, 0);
return result;
}
}
});
//对外暴露方法
export default useInfoStore;
组件使用pinia进行操作数据代码示例:
父组件:parentComponents.vue
<template>
<div class="box">
<h1>pinia</h1>
<div class="container">
<Child></Child>
<Child1></Child1>
</div>
</div>
</template>
<script setup lang="ts">
import Child from "./Child.vue";
import Child1 from "./Child1.vue";
//vuex:集中式管理状态容器,可以实现任意组件之间通信!!!
//核心概念:state、mutations、actions、getters、modules
//pinia:集中式管理状态容器,可以实现任意组件之间通信!!!
//核心概念:state、actions、getters
//pinia写法:选择器API、组合式API
</script>
子组件1:Child.vue (在组件中使用store仓库到处的方法,获取到小仓库对象,通过调用仓库actions中的方法updateNum进行数据的更改,这时候数据会同步存储到仓库中,由于vue的数据是双向绑定的,所以仕途的数据也会伴随事件执行,数据更改随之变化)
<template>
<div class="child">
<h1>{{ infoStore.count }}---{{infoStore.total}}</h1>
<button @click="updateCount">点击我修改仓库数据</button>
</div>
</template>
<script setup lang="ts">
import useInfoStore from "../../store/modules/info";
//获取小仓库对象
let infoStore = useInfoStore();
console.log(infoStore);
//修改数据方法
const updateCount = () => {
//仓库调用自身的方法去修改仓库的数据
infoStore.updateNum(66,77);
};
</script>
子组件2:Child1.vue (第二个子组件同第一个组件一样的原理,都是通过组合式API函数仓库将数据进行更改)
<template>
<div class="child1">
{{ infoStore.count }}
<p @click="updateTodo">{{ todoStore.arr }}{{todoStore.total}}</p>
</div>
</template>
<script setup lang="ts">
//引入组合式API函数仓库
import useTodoStore from "../../store/modules/todo";
let todoStore = useTodoStore();
//点击p段落去修改仓库的数据
const updateTodo = () => {
todoStore.updateTodo();
};
</script>
子组件2对应仓库代码(todo.ts)
//定义组合式API仓库
import { defineStore } from "pinia";
import { ref, computed, watch } from "vue";
//创建小仓库
let useTodoStore = defineStore("todo", () => {
let todos = ref([
{ id: 1, title: "吃饭" },
{ id: 2, title: "睡觉" },
{ id: 3, title: "打豆豆" },
]);
let arr = ref([1, 2, 3, 4, 5]);
const total = computed(() => {
return arr.value.reduce((prev, next) => {
return prev + next;
}, 0);
});
//务必要返回一个对象:属性与方法可以提供给组件使用
return {
todos,
arr,
total,
updateTodo() {
todos.value.push({ id: 4, title: "组合式API方法" });
},
};
});
export default useTodoStore;
4️⃣ Pinia与Vuex的区别
- 响应式设计:
- Vuex 使用了基于 Mutation 和 Action 的同步和异步方式来管理状态。它的状态是通过 mutations 同步地改变,actions 可以包含异步逻辑。
- Pinia 利用 Vue 3 的响应式系统,利用 Composition API 来创建 Stores,这意味着 Pinia 中的状态是通过响应式数据进行管理。它的设计更加简单、直接,直接使用 Vue 3 的响应式 API。
- API 设计:
- Vuex 使用了比较传统的设计方式,包括 mutations、actions、getters 等概念,需要使用对象风格来管理状态。
- Pinia 使用了更简洁和直接的 API 设计,利用 Vue 3 的 Composition API,更加灵活,并且与 Vue 3 中的 API 更贴合。
- 模块化和组合性:
- Vuex 具有模块化的能力,可以将状态划分为不同的模块,但模块间的组合并不是特别直接。
- Pinia 的模块化设计更加清晰和直接,Stores 可以更容易地相互组合和重用,因为它们是基于 Composition API 构建的。
- 兼容性:
- Vuex 是为 Vue 2 设计的主要状态管理工具,虽然也能在 Vue 3 中使用,但可能需要使用特定的适配器或插件。
- Pinia 是为 Vue 3 设计的,充分利用了 Vue 3 的 Composition API,更加贴合 Vue 3 的特性。
- 体积:
- 由于 Pinia 是专门为 Vue 3 设计的,因此可以更好地利用 Vue 3 的特性,可能在某些方面有更小的体积或更好的性能优化。
🤗 总结归纳
- 直接性和简洁性:Pinia 的 API 设计简单直接,基于 Vue 3 的 Composition API,使得状态管理变得直观且容易上手。它不需要像 Vuex 那样定义 mutations 和 actions,使得状态管理的代码更加简洁明了。
- 模块化和组合性:Pinia 支持模块化的 Store 设计,每个 Store 可以独立定义自己的状态和操作,并且可以轻松地被其他 Store 组合使用,这种灵活性有助于代码的重用和维护。
- 与 Vue 3 的兼容性:由于 Pinia 是为 Vue 3 设计的,它充分利用了 Vue 3 的特性,与 Composition API 很好地契合,因此对 Vue 3 项目具有天然的兼容性,可以更好地利用 Vue 3 的优势。
- 性能优化:Pinia 利用了 Vue 3 的响应式系统,能够更高效地管理状态,并且利用更少的内存开销。这使得 Pinia 在处理大型应用或复杂状态时表现良好。
- 文档和社区支持:Pinia 提供了详细的文档和示例,方便用户学习和使用。尽管 Pinia 相对较新,但它正在逐渐建立其社区支持和生态系统。
- 轻量级和灵活性:Pinia 的体积较小,它专注于提供简洁、灵活和可维护的状态管理解决方案。它不强制性地增加额外的复杂性,允许开发者按需添加自定义功能。