Pinia是Vue.js 3的状态管理库,使用起来非常简单和直观
Pinia的优点大致如下
TypeScript支持:Pinia使用TypeScript编写,并提供完整的类型支持,这使得编写类型安全的代码变得更加容易和直观。
简单易用:Pinia的设计非常简单,只有一个Store的概念,使用起来比Vuex更加容易。
更好的性能:Pinia使用Vue 3的新特性,如响应式API和新的组件实例化方式,这使得它的性能比Vuex更高。
模块化:Pinia的模块化设计非常好,可以轻松地将功能模块拆分成独立的Store实例。
更好的测试支持:Pinia对测试有很好的支持,可以轻松地编写测试代码,并且不需要太多的mock代码。
一、安装使用Pinia
- 1.1使用npm或yarn安装Pinia:
npm install pinia
# or with yarn
yarn add pinia
- 1.2在入口文件main.js中注册Pinia
import { createPinia } from 'pinia'
app.use(createPinia())
- 1.3在src目录下新建store/index.js
import { defineStore } from 'pinia'
// 第一个参数 storeId 是仓库的key 必须独一无二
export const useStore = defineStore('storeId', {
state: () => {
return {
count: 0,
name: "张三"
}
},
getters:{},
actions:{}
})
- 1.4在组件中使用Pinia的state数据
<template>
<div>
<h1>组件</h1>
{{ count }}
</div>
</template>
<script setup>
import { useStore } from '@/store/index'
const store = useStore();
const { name } = store;
</script>
-
1.5组件修改Pinia中的数据
本身pinia可以直接修改state数据,无需像vuex一样通过mutations才可以修改,但是上面写的const { name } = store;这种解构是不可以的,所以要换解构的方式。
<template>
<div>
<h1>组件</h1>
{{ count }}
</div>
</template>
<script setup>
import { storeToRefs } from 'pinia'
import { useStore } from '@/store/index'
const store = useStore();
// 第一种、直接修改
store.count++
// 第二种、调用$patch方法修改
countStore.$patch({
count: store.count+2
})
// 第三种
// pinia提供了 一个 storeToRefs 方法 类似于 vue3中 toRefs
const { count } = storeToRefs(store);
count.value = 1000;
</script>
- 1.6 getters的使用
getters和vuex里的getters几乎类似,基于 已有的state 进行计算得到新值,会基于依赖进行缓存,多次使用依赖不变 不会重新计算
import { defineStore } from 'pinia'
// 第一个参数 storeId 是仓库的key 必须独一无二
export const useStore = defineStore('storeId', {
state: () => {
return {
num: 10,
name: "张三"
}
},
getters:{
// 1 箭头函数写法 参数是state
doubleNum: state => {
return state.num * 2
},
// 2 对象方法写法
tribleNum(state){
return state.num*3
}
},
actions:{}
})
组件中使用getters
<template>
<div>
{{ doubleNum }}
{{ tribleNum }}
{{ tribleNum }}
<h1>组件</h1>
{{ num }}
</div>
</template>
<script setup>
import { storeToRefs } from 'pinia'
import { useStore } from '../store/index'
const store = useStore();
//直接使用
console.log(store.doubleNum )
//解构
const { num, doubleNum, tribleNum} = storeToRefs(store);
</script>
- 1.7 actions的使用
actions就比较简单了,写入方法,比如我们可以让state中的某一个值+=,而且传入参数
import { defineStore } from 'pinia'
// 第一个参数 storeId 是仓库的key 必须独一无二
export const useStore = defineStore('storeId', {
state: () => {
return {
num: 10,
name: "张三"
}
},
getters:{
// 1 箭头函数写法 参数是state
doubleNum: state => {
return state.num * 2
},
// 2 对象方法写法
tribleNum(state){
return state.num*3
}
},
actions:{
addNum(n) {
// 直接通过this 千万不要写箭头函数
this.num += n
}
}
})
组件中使用
<script setup>
import { storeToRefs } from 'pinia'
import { useStore } from '../store/index'
const store = useStore();
//直接使用
store.addNum(100)
</script>
二、Pinia怎么分模块?
Pinia不需要像Vuex一样使用modules分模块,Pinia可在store目录中直接定义对应模块就可以了,简洁明了
- 2.1 目录结构
store/user.ts //用户模块
store/shop.ts //商品模块
...
- 2.2 store/user.ts
import { defineStore } from 'pinia'
export const user = defineStore({
id: 'user',
state:()=>{
return {
userInfo:{
nickName:'admin'
},
token:'xdsrrd-fsdsdsd02d5sdsd-dsds'
}
},
getters:{
},
actions:{
}
})
- 2.3组件中使用
<template>
<div>
<h1>A组件</h1>
{{ userInfo.nickName }}
</div>
</template>
<script setup>
import { storeToRefs } from 'pinia'
// 模块一
import { useStore } from '../store/index'
const store = useStore();
// 模块二
import { user } from '../store/user'
const store = user();
// 使用语法同上
</script>
三、Pinia持久化存储
- 3.1安装插件
npm i pinia-plugin-persist --save
- 3.2 在入口文件main.js中引入
import { createPinia } from "pinia";
import piniaPluginPersist from "pinia-plugin-persist"; //pinia持久化
const pinia = createPinia();
pinia.use(piniaPluginPersist);
- 3.3 在store中使用
export const useStore = defineStore("main", {
state:()=>{
return {
}
},
getters:{
},
actions:{
}
//持久化
persist: {
enabled: true,
// 自定义持久化参数
strategies: [
{
// 自定义key,默认就是仓库的key
key: "token",
// 自定义存储方式,默认sessionStorage
storage: localStorage,
// 指定要持久化的数据,默认所有 state 都会进行缓存,可以通过 paths 指定要持久化的字段,其他的则不会进行持久化。
paths: ["token"],
},
{
key: "menulist",
storage: localStorage,
paths: ["menulist"],
},
],
},
});
若有不足,请各位大佬补充,欢迎指正。。。