一、Pinia简介
Pinia是Vue的存储库,可以跨组件/页面共享状态。
- Vue2和Vue3都能使用
- 抛弃了Mutations的操作,只有state、getters和actions,代码更加简洁
二、安装开发环境
1.初始化vite
npm init vite@latest //设置项目名称、开发语言
2.启动项目
npm install
npm run dev
3.安装pinia
npm install pinia
三、创建store
1.在main.js文件里引入Pinia
import { createPinia } from 'pinia'
//创建pinia实例
const pinia = createPinia()
//挂载到vue的根实例上
app.use(pinia)
2.在src文件夹创建store文件
- defineStore()第一个参数,相当于为容器起一个名字,注意:这个名字必须是唯一的
- defineStore()第二个参数,为容器仓库的配置对象
- state:用来储存全局状态的
- getters:用来计算状态变化的,有缓存的功能
- actions:根据不同的业务逻辑编写对应的功能代码,修改state状态数据
//store文件夹/index.js文件
import {defineStore} from 'pinia'
export const demo1Store = defineStore('demo1',{
state:()=>{
return {
school:'测试名称', //这个数据是全局的状态数据,每个页面和组件都可通过Pinia方法读取
count: 0,
}
},
getters: {},
actions: {}
})
3.在组件/页面使用Store数据
<template>
<div class="page">
<h2>
{{store.school}}
{{store.count}}
</h2>
<button @click="clickAdd">增加</button>
</div>
</template>
<script>
import {demo1Store} from '@/store.index'
export default{
setup(){
const store = demo1Store()
const clickAdd = ()=>{
//直接改变store.count的值,适用于修改单条数据
store.count ++
}
return {
store,
clickAdd
}
}
}
</script>
注意事项:
如果采用解构的方式,获取store的值,直接使用的话,数据并没有发生变化,因为该数据不是响应式的。为此,Pinia官方提供了storeToRefs()方法
import {storeToRefs} from 'pinia'
const {school, count} = storeToRefs(store)
五、修改数据的其他方式
1.使用 p a t c h 修改多条数据,如果是多条数据同时需要更新,推荐使用 patch修改多条数据,如果是多条数据同时需要更新,推荐使用 patch修改多条数据,如果是多条数据同时需要更新,推荐使用patch
<button @click="clickPatchMethod">增加按钮并修改文字</button>
//在组件或页面中编写方法
const clickPatchMethod = ()=>{
store.$patch({
count: store.count + 2,
school: store.school = 'hello school'
})
}
2.$patch加函数的方式修改状态数据
上面的方法,参数使用的是一个对象,比较适合复杂数据的修改,比如数组、对象
const clickPatchFun = ()=>{
store.$patch(state)=>{
state.count++
state.school = '函数形式的'
}
}
3.在actions里面写逻辑,然后在页面中直接调用
如果修改的过程非常复杂,可以直接在store里面定义actions函数,然后在组件或页面中调用
actions: {
//不能使用箭头函数,因为箭头函数绑定的是外部的this
changeState(){
this.count ++
this.school = 'change hello'
}
}
在组件中直接使用actions方法
<button @click="clickAdd">点击增加<button>
const clickAdd = ()=>{
store.changeState()
}
6.Getters使用
1.编写getters
在store文件中增加getters的方法
state:()=>{
return{
count: 0,
}
}
getters: {
zoomCount(state){
console.log("被调用了")
return state.count * 10
}
}
在组件中调用getters
getters是有缓存特性的,如果在组件中调用了两次,但是看控制台打印,只有一个"被调用了"
<template>
<div>
<h2>
{{store.zoomCount}}
</h2>
</div>
</template>
<script>
import {demo1Store} from "@/store/index"
export default{
setup(){
const store = demo1Store()
return {
store
}
}
}
</script>
3.getters中this的使用
可以在actions里直接使用this
getters同样也可以使用this
//使用this的写法
getters:{
zoomCount(){
return this.count * 10
}
}
七、多个store
pinia是可以有多个store的
1.在store文件夹中新建一个demo2仓库
import {defineStore} from 'pinia'
export const demo2Store = defineStore('demo2',{
state:()=>{
return {
list:['班级1','班级4']
}
},
getters:{},
actions:{}
})
2.在demo1Store中引入刚刚创建的demo2Store
import {demo1Store} from './demo2Store'
actions:{
changeState(){
this.count ++
}
getList(){
console.log(demo1Store().list) //可以直接获取到另外store的数据
}
}
4.在页面中调用
<button @click="getList">store的相互调用</button>
const getList = ()=>{
store.getList()
}