什么是 Pinia?
pinia 是由 vue 团队开发的,适用于 vue2 和 vue3 的状态管理库,它允许您跨组件/页面共享状态; 主要侧重于vue3的组合式API,当然Vue2也是可以使用的,本篇将介绍的是vue3使用;
与vuex3或vuex4的比较:
Pinia 不需要额外的Map辅助函数;(setup和组合式Api的使用Pinia更容易,因此不需要map helpers 功能); Pinia 相比vuex的模块少了Mutaions和Modules;只保留了(State、Getters、Actions以及新增了Plugins); Pinia 没有命名空间模块; Pinia 是平面结构(利于解构),没有嵌套,可以任意交叉组合;
为什么使用Pinia?
- dev-tools 支持(安装和使用链接)
- 热更新(在不重新加载页面的情况下修改 Store)
- 可以使用插件扩展 Pinia 功能
- 为 JS 用户提供适当的TypeScript支持或自动填充
- 服务器端渲染支持
1,安装Pinia
yarn add pinia
# 或者使用 npm
npm install pinia
2 ,Pinia 的引入 一般我们在做项目的时候,都会在main.js 或者 main.ts 中引入。 vue3 中引入的使用
import { createPinia } from "pinia";
app.use(createPinia());
3,Pinia的结构 上面也说到: Pinia 没有命名空间模块;只有State、Getters、Actions模块 Pinia 是平面结构(利于解构),没有嵌套,可以任意交叉组合。
4,Pinia使用
下图是Demo演示的例子: 大家可以拷贝下来自己运行一下,注释都写的非常清楚:
1,State 是store 的核心部分。 在 Pinia 中,状态被定义为返回初始状态的函数; 2,Getters 完全等同于 Store 状态的计算值。可以用 defineStore() 中的 getters 属性定义。 接收“状态”作为第一个参数和鼓励箭头函数的使用; 3,Actions 相当于组件中的 methods。可以使用 defineStore() 中的 actions 属性定义,并且非常适合业务逻辑的处理以及异步的请求;
counter.js
import { ref, computed } from "vue";
import { defineStore } from "pinia";
import { rootSore } from "@/stores/rootState";
export const useStore = defineStore("myId", {
state: () => {
return {
counter: 100,
name: "Eula",
isAdmin: true,
};
},
getters: {
doubleCount: (state) => {
return state.counter * 2;
},
trebleCount() {
return this.counter * 3;
},
receiveParams: (state) => {
return (params) => {
console.log("params:", params);
return String(params) + state.name;
};
},
useOtherStateOfModules: (state) => {
const otherStore = rootSore();
return state.name + "-" + otherStore.age;
},
},
actions: {
induce() {
console.log(1111);
this.counter--;
},
randomizeCounter() {
this.counter = Math.round(100 * Math.random());
},
},
});
组价中使用:
<template>
<div class="demo">
<h2>This is a Demo Of Pinia To Used</h2>
<p class="store">store数据:{{ store.counter }}</p>
<!--下面了使用了pinia里面的计算属性 -->
<p class="store">双倍数据:{{ store.doubleCount }}</p>
<!-- 下面是传参的 getter -->
<p class="store">传参的计算属性:{{ store.receiveParams("我的") }}</p>
<!-- 下面是使用了其他模块数据的 getter -->
<p class="store">
使用其他模块数据的计算属性:{{ store.useOtherStateOfModules }}
</p>
<div class="btnContent">
<button class="btn" @click="add">点击加一</button>
<button class="btn" @click="reduce">点击减一</button>
<button class="btn" @click="reset">重置Pinia状态</button>
</div>
</div>
</template>
<script setup>
import { reactive, ref, createApp, onMounted } from "vue";
import { storeToRefs } from "pinia";
import { useStore } from "@/stores/counter";
let store = useStore();
const add = () => {
store.name = "Wendi";
store.counter++;
console.log("name:", store.name);
};
const reduce = () => {
store.induce();
console.log("counter:", store.counter);
};
const reset = () => {
store.$reset();
};
</script>
<style>
.btnContent {
margin-top: 10px;
}
.btn {
margin-left: 10px;
}
.store {
margin-left: 10px;
}
</style>
rootState.js (这是另一个模块,在counter.js模块会用到的)
import { defineStore } from "pinia";
export const rootSore = defineStore("rootId", {
state: () => {
return {
age:18,
};
},
});
5,重置状态 如果想要将数据重置到最开始更新数据的时候,pinia提供了一个方法:$reset();
6,总结 Pinia相对于vuex来说,确实减少的代码量,尤其删除了Mutations模块,在Pinia可以直接对状态进行修改;优化了原先多层嵌套的模块化,使每个模块都能任意访问,交叉组合;
|