Vue3中状态管理pinia学习原创
vue3成为默认版本,pinia状态管理是vue官方人员出的,比vuex更加方便。它有以下几个优点:
- 同时支持vue2和vue3
- 状态管理库的简化,只有state、getters、actions
- 不需要嵌套模块,符合vue3的Composition api
- typescript支持
- 代码更加简洁
我跟着一块了解了下pinia状态管理的环境搭建、store创建、状态数据改变方式以及注意事项、还包括getters使用以及store的相互调用方面内容。
# 一、Pinia简介和开发环境搭建
# 1.Pinia简介
Pinia是Vue生态里Vuex的代替者,一个全新Vue的状态管理库。Pinia的优势就是:更加简洁的语法,完美支持Vue3的Composition api 和对 TypeScript 的完美支持。
# 2.Pinia开发环境搭建
# Vue3环境安装
Pinia是Vue的状态管理库,所以首先需要创建Vue的项目环境,我采用的是Vite来搭建Vue3环境。(也可以用Webpack来搭建,哪个熟悉用哪个)
①初始化vitenpm init vite@latest
②输入项目名称? Project name: » vite-project
,这里我起名vite-pinia-demo
③选择项目框架,这里选择vue或者vue-ts,我这里选择vue-ts
? Select a framework: » - Use arrow-keys. Return to submit.
> vanilla
vue
react
preact
lit
svelte
2
3
4
5
6
7
④现在项目已经初始化完成,按照下面提示顺序来跑通Vue3项目
Done. Now run:
cd vite-pinia-demo
npm install
npm run dev
2
3
4
⑤直到出现下列代码,复制网址能够正常访问页面说明Vue3项目环境初步搭建好了。
vite v2.8.3 dev server running at:
> Local: http://localhost:3000/
> Network: use `--host` to expose
ready in 392ms.
2
3
4
5
6
# Pinia的安装
Vue3环境搭建好了后,开始安装Pinia状态管理库。
安装pinia:npm install pinia
如何确认安装成功:在项目文件夹根目录中package.json文件中确认依赖项中是否存在pinia。
"dependencies": {
"pinia": "^2.0.11",
"vue": "^3.2.25"
}
2
3
4
# 二、用Pinia的方式创建一个store
# 在main.ts中引入Pinia
在/src/main.ts中需要引入Pinia,因为main.ts是Vue3项目中根实例引入的文件
首先引入Pinia,import {createPinia} from 'pinia'
然后创建pinia实例,const pinia = createPinia()
最后将pinia实例挂载到Vue的根实例上
const app = createApp(App)
//挂载到 Vue 根实例上
app.use(pinia)
app.mount('#app')
2
3
4
5
# 创建store状态管理库
首先在/src目录下,新建状态管理store文件夹,并在该文件夹下创建一个index.ts状态管理文件;
在状态管理index.ts文件中:
- 定义状态容器
- 修改容器中的state
- 容器中getters和actions的使用
书写格式如下:
import { defineStore } from "pinia"
export const myStore = defineStore('myStore',{
state:()=>{
return{}
},
getters:{},
actions:{}
})
2
3
4
5
6
7
8
9
defineStore()方法接收两个参数:
第一个参数是容器的名字,需要保证是唯一的;
第二个参数是要配置的对象,包括以下三个属性:
- state:存储全局状态;
- getters:类似于Vue中的计算属性,用来计算状态的变化,具有缓存的功能
- actions:针对state状态数据来编写复杂的业务逻辑代码
# 在Vue3组件中读取store数据
首先在/src/store/index.ts的state中添加数据:
state:()=>{
return{
data:'Hello Pinia!'
}
},
2
3
4
5
然后在/src/components/下新建一个组件piniaTest.vue:
<template>
<h2>{{store.data}}</h2>
</template>
<script lang="ts" setup>
import { myStore } from '../store/index.'
const store = myStore()
</script>
<style scoped>
</style>
2
3
4
5
6
7
8
9
再将piniaTest.vue组件引入到App.vue中:
<script setup lang="ts">
import piniaTestVue from './components/piniaTest.vue';
</script>
<template>
<piniaTestVue/>
</template>
<style>
</style>
2
3
4
5
6
7
8
9
10
重新在终端输入npm run dev
运行,打开网页可以看到状态管理库中存储的数据“Hello Pinia!",则完成了Pinia状态管理库的构建并可以在其他组件中使用状态管理数据!
# 三、Pinia改变状态数据和注意方式
# 实现状态数据的改变
上一节中实现了对于状态数据的读取,步骤是:首先引入状态管理库,然后实例化,再通过对象引用的方式读取状态数据。这一节再来验证一下状态数据的改变,步骤和读取类型,只不过是加入一个方法来对状态数据进行改变,来看状态数据是否可以响应式更新在界面上。
首先在store/index.ts中state加入新的状态数据count:
state:()=>{
return{
data:'Hello Pinia!',
count:0
}
},
2
3
4
5
6
再components文件夹下新建一个组件piniaChange.vue:
<template>
<div><button @click="handleClick">点击count加1</button></div>
</template>
<script lang="ts" setup>
import { myStore } from '../store/index.'
const store = myStore()
const handleClick = ()=>{
store.count++
}
</script>
<style scoped>
</style>
2
3
4
5
6
7
8
9
10
11
12
13
然后将此组件也引入到App.vue中:
import piniaChangeVue from './components/piniaChange.vue';
<template><piniaChangeVue/></template>
2
3
但是count数据还未加入在组件中去,所以还测试不了count数据变化,选择把count状态数据加入上一节创建的piniaTest.vue中:
<template>
<h2>{{store.data}}</h2>
<h2>count:{{store.count}}</h2>
</template>
2
3
4
最后,重新跑下项目,通过点击按钮就可以在页面上响应式看到count的改变。好啦,通过一顿操作验证了状态数据的改变。
# 状态数据读取时注意事项
在读取状态数据时,之前采用的方式是通过引入状态文件,实例化对象,再到对象读取的方式。可以通过对实例化对象结构的方式来读取数据:
<template>
<h2>{{store.data}}</h2>
<h2>count:{{store.count}}</h2>
<hr>
<h2>{{data}}</h2>
<h2>count:{{count}}</h2>
</template>
<script lang="ts" setup>
import { myStore } from '../store/index.'
const store = myStore()
const {data,count} = store
</script>
<style scoped>
</style>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
但是直接解构得到的数据并不是响应式数据,当count数据改变时,解构的数据并不会跟着发生变化。
解决办法:通过在pinia引入
storeToRefs()
方法,解构时对要解构的对象采用此方法,可以实现数据响应式变化了。
# 四、Pinia改变状态数据的四种方式
# 通过对象读取方法
前一节就是采用这种方法的读取并改变状态数据的。适用于简单的业务逻辑数据改变。
# 通过$patch修改多条数据
首先创建方法:
const handleClickPatch = ()=>{
store.$patch({
count:store.count + 2,
})
}
2
3
4
5
然后通过按钮调用该方法:
<div><button @click="handleClickPatch">Patch点击count加2</button></div>
优点:可以在$patch方法中写入多条状态数据改变,同时此方法是官方经过优化的,相比于直接修改来说修改速度更快,适用于多条数据同时更新状态。
# 直接在acitons中写好逻辑,再调用actions
在/store/index.ts的actions中写入actions:
actions:{
changeState(){
this.count++
this.data = 'Hello Actions'
}
}
2
3
4
5
6
然后通过调用该actions:
<div><button @click="store.changeState()">Action点击count加1</button></div>
注意:actions中方法书写不能使用箭头函数,否则this指向位置发生错误。
# 五、Pinia中getters的使用
# getters使用
getters与vue中的计算属性很相似,用于在获取状态数据时做一些处理。比如说state状态中有word状态数据,输出时想要保证是全大写的,以此为例。
首先增加word状态数据:
state:()=>{
return{
data:'Hello Pinia!',
count:0,
word:'Lowcase'
}
},
2
3
4
5
6
7
书写getters:
getters:{
wordToUpper(state){
return state.word.toLocaleUpperCase()
}
},
2
3
4
5
在组件中引入和调用:
const {data,count,wordToUpper} = storeToRefs(store)
<h2>{{wordToUpper}}</h2>
2
3
重新跑通系统,可以看到word状态数据都变为大写的。
# getters编写时this使用
在书写getters时,可以传入state参数,直接在内容使用this来代替state。
# getters缓存特性
getters具有缓存特性,当多次调用getters内同一个函数时,它只会执行一次调用。
可以在getters内函数打印调用信息来验证,当多次调用该函数时,发现控制台只打印了一次调用信息。
getters:{
wordToUpper(state){
console.log('wordToUpper被调用了!')
return state.word.toLocaleUpperCase()
}
},
2
3
4
5
6
当状态数据发生改变时,被调用的函数才会重新执行一次,不管是有多少地方调用该函数。
通过按钮调用改变状态数据方法可以验证:
const handleClickToUpper = ()=>{
store.word = 'pinia'
}
2
3
点击按钮后,即使有多处调用getters,控制台仍只打印一次调用信息。
# 六、Pinia中store的相互调用
pinia状态管理中有多个store时,就会涉及store间的相互调用。
# 新建一个store容器
在/src/store下新建文件another.ts:
import { defineStore } from "pinia";
export const anotherStore = defineStore('anotherStore',{
state:()=>{
return{
songsList:['love story','lover','All to well']
}
},
getters:{},
actions:{}
})
2
3
4
5
6
7
8
9
10
11
# 在另一个容器中引入
在index.ts中引入新建的store容器:
import { anotherStore } from '../store/another';
在index.ts中actions中调用另一个store状态数据
actions:{
changeState(){
this.count++
this.data = 'Hello Actions'
},
getSongList(){
console.log(anotherStore().songsList)
}
}
2
3
4
5
6
7
8
9
再通过组件定义按钮来调用actions方法:
<div><button @click="store.getSongList">getList</button></div>
点击按钮可以看到控制台打印出信息,即完成了store间的调用。
# 七、Pinia在开发中用vue-devtools的调试方法
# vue-devtools安装
vue-devtools是很好用的vue调试工具,可以在谷歌商店下载或者在github上下载自己跑通再安装。
# vue-devtools对Pinia的调试
安装后打开控制台的vue选项卡,可以看到vue中引入的组件;
组件中显示小菠萝图标的就是代表store状态容器;还可以在组件中筛选出使用pinia状态管理的组件。
以上是Pinia开发环境搭建和基础学习的内容了,完整示例代码上传到了github上,链接 (opens new window)。
参考链接: