什么是Pinia
Pinia是一个为Vue.js设计的状态管理库,它的设计目标是为了提供一种更简洁、更直观的方式来处理跨组件状态共享的问题。Pinia可以被视为Vue的Vuex库的一种替代方案,尤其是在Vue 3的背景下,它利用了Vue 3中引入的Composition API以及TypeScript的支持。
安装Pinia
安装Pinia这很简单,在我们Vscode的Vue项目中打开终端输入
yarn add pinia
# 或者使用
npm npm install pinia
等待安装完成就好了
使用Pinia基础用法
在使用Pinia之前,我们来探讨一个问题。在vue的组件通讯中存在父子组件通讯,子父组件通讯,那么如果我们想要兄弟组件通讯呢,又该如何实现。理论上来说我们可以由子组件1通过defineEmits声明一个事件,再由父组件通过订阅该事件获取到值,再通过v-bind绑定数据传给子组件2实现兄弟组件通讯,但是这样是否会显得工作量会大那么一丢丢呢。诶,所以我们就可以使用Pinin来完成,下面我将为大家介绍Pinia中的三个核心概念
Store
Store是一个保存状态和业务逻辑的实体,它不会和组件树进行绑定,可以把它看成一个全局的实体,每一个组件都可以读取和写入它
我们在src文件夹下创建一个index.js文件,用于创建一个Pinia实例对象
import {createPinia} from 'pinia';
//创建一个仓库
const store = createPinia();
export default store;
这样我们创建好了一个Pinia实例对象,然后在我们全局文件main.js中引入并使用即可
import { createApp } from 'vue'
import App from './App.vue'
import store from './store'
createApp(App).use(store).mount('#app')
而定义一个Store也是挺简单的,在Pinia官方API文档中是这样写的

State
State可以被理解为一个数据源的存在,它通常用来存放一些数据

Getter
Getter可以被理解为Store中的一个计算属性,它专用于计算值
Action
Action可以被理解为Store中的Method,里面可以下函数,值得注意的是
Getter中的函数天生带有一个形参state,代表仓库的数据源.
简单的综合运用
现在就让我们简单的使用他们吧。首先我们先创建一个App.vue
文件,我们在src文件夹下的components文件夹下分别创建User.vue和Update-user.vue文件。
我们再把User.vue和Update-user.vue文件作为App.vue文件的子组件使用
//App.vue
<template>
<div>
<User/>
<Updateuser />
</div>
</template>
<script setup>
import User from './components/User.vue'
import Updateuser from './components/Update-user.vue'
</script>
<style lang="css" scoped>
</style>
现在我们分工一下User.vue中我们用于显示数据,Update-user.vue我们用于实现操作。最后在src文件下的store文件夹中创建user.js文件用于数据处理。
第一步我们首先要在user.js中定义一个Store,并给它设置一个唯一的Id
import {defineStore} from 'pinia';//defineStore 是store的一部分
export const useUserStore = defineStore({
id:'user'
})
然后我们把State,Getter,Action写好,在这里我给数据源State先写好一个userInfo对象
import {defineStore} from 'pinia';//defineStore 是store的一部分
export const useUserStore = defineStore({
id:'user',
state:()=>{ //整个仓库的数据源
return {
userInfo:{
name:'老六',
age:18,
sex:'gril'
}
}
},
actions:{ //专门用来修改state中的数据
},
getters:{ //仓库中的计算属性
}
})
然后我们需要在User.vue中引入useUserStore,通过调用useUserStore()得到useUserStore仓库,也就是
在State中返回了一个对象userInfo所以我们可以直接获取到返回对象的值。因为我们的页面会进行数据修改,所以这里为大家介绍两种把数据变成响应式数据的方法,第一种是vue中自带的计算属computed,第二种是pinia中的storeToRefs
<template>
<ul>
<li>姓名:{{userStore.userInfo.name}}</li>
<li>年龄:{{age}}</li>
<li>十年之后:{{userStore.afterAge}}</li>
<li>性别:{{userInfo.sex}}</li>
</ul>
</template>
<script setup>
import {useUserStore} from '@/store/user'
import {computed} from 'vue'
import {storeToRefs} from 'pinia'
const userStore = useUserStore()//得到useUserStore仓库
const age = computed(()=>userStore.userInfo.age)
// 把仓库中的值包裹起来,变成响应式 其自带返回一个对象,需要结构
const {userInfo} = storeToRefs(userStore)
</script>
<style lang="css" scoped>
</style>
接下来让我们在Update-user中完成三个操作
<template>
<button @click="changeName">修改仓库中的用户的姓名</button>
<button @click="changeSex">修改仓库中的用户的性别</button>
<button @click="changeAge">修改仓库中的用户的年龄</button>
</template>
修改姓名,修改年龄,更改性别。三个操作,所以我们定义三个函数ChangeName(),changeSex(),ChangeAge()
我们修改数据,是不是修改useuserStore中的数据,所以我们要调用useuserStore中自己的函数来实现数据修改。
<script setup>
import {useUserStore} from "@/store/user"
const userStore = useUserStore()
const changeName = () =>{
// userStore.userInfo.name = '老王'
userStore.changeUserName('老王');
}
const changeSex = () =>{
// userStore.userInfo.sex = 'gril'
userStore.changeUserSex('boy');
}
const changeAge = ()=>{
userStore.changeUserAge(1)
}
</script>
我们分别调用useuserStore中自己的三个函数changeUserName,changeUserSex,changeUserAge,现在我们回到user.js中实现这三个函数
actions:{ //专门用来修改state中的数据
changeUserName(name){
this.userInfo.name = name
},
changeUserSex (sex){
this.userInfo.sex = sex
},
changeUserAge(n){
this.userInfo.age += n
}
}
this指代的是state.我们注意到在User.vue中还有一个是计算十年之后的年龄,这里我们就可以使用Getter计算属性了
getters:{ //仓库中的计算属性
// getters中的函数天生带有一个形参state,代表仓库的数据源
// getters中的函数名称就是这个函数返回出来的属性 不需要我们调用 我们直接userStore.afterAge就可以了
afterAge(state){
return state.userInfo.age+10
}
},
这样我们就基本实现了功能,但是依旧存在一个问题。当我们页面刷新之后,数据就会清零,需要重新执行。
所以我们给Store添加一个持久化数据的功能,用的是persist,这段内容我们先安装依赖
npm i pinia-plugin-persist
然后我们再把它引入index.js中,并使用
//index.js
import {createPinia} from 'pinia';
import piniaPluginPersist from 'pinia-plugin-persist'
//创建一个仓库
const store = createPinia();
store.use(piniaPluginPersist);
export default store;
然后在我们的user.js中实现
persist:{ //开启数据持久化
enabled:true,
strategies:[
{
paths:['userInfo'],
// 持久化存储的位置
storage:localStorage
}
]
}
paths是需要存入我们需要保存的数据,而storage是我们可以选择数据保存方式,在浏览器中我们有localStorage,Cookie,Session,IndexedDB等多种数据存储方式,这里我们选择localStorage的存储方式。
这样我们就实现了数据存储
回到我们开始提到的兄弟组件如何实现兄弟组件之间通讯呢,这里我们的Update-user.vue和User.vue是兄弟组件,我们点击Update-user.vue中的按钮,就会修改User.vue展示的数据,这就完成兄弟组件通讯。
文章若有不足,恳请各位指出,感谢大家阅读!!