我们把数据存放在state中,如果修改它的话,就要使用pinia中另外一个重要的概念actions了。
如果与Vuex对比,pinia中的action相当于Vuex中mutation和action的总和。
在pinia的action中既可以处理同步修改,也可以处理异步。简化了Vuex中修改状态的概念。
同步修改
我们先来写一个同步修改的例子,
比如我们现在除了保存了用户名,还保存了用户的手机号码,然后增加一个修改手机号码的方法,这时就需要定义一个action了。
pinia官网也说明了,actions就相当于vue中methods,定义的时候也非常像:
import { defineStore } from 'pinia'
export const useProfileStore = defineStore('profile', {
state() {
return {
userName: '林哥',
phone: 18888888888,
}
},
actions: { // 和vue中的methods一样
updatePhone(newPhone) {
this.phone = newPhone // 可以使用this访问和修改state中的数据
},
},
})
我们在actions中定义了一个更新手机号的方法,它接受一个参数,把它设置为新的手机号
然后我们就可以在App.vue中调用这个方法了:
用户名是: {{ profileStore.userName }}
手机号是: {{ profileStore.phone }}
使用store的实例就可以直接调用store中定义的action,这我们调用updatePhone方法,修改了手机号,
刷新页面,这时页面上显示:
用户名是: 林哥
手机号是: 19999999999
异步修改
首先我们写一个模拟请求后台接口,
在src文件夹下建立一个api文件,然后在里面新建一个login.js的文件,它的内容是:
export function loginApi(userName, password) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if ((userName === '林哥') & (password === '9527')) {
resolve({
userName: '林哥',
phone: 18888888888,
avatar: 'avatar.jpg',
})
} else {
reject('用户名或密码错误')
}
}, 1000)
})
}
然后我们修改profileStore的内容,在state中新增了avatar头像这个属性,这些数据默认都是空,
在actions中新增了login,用于去调用异步的请求loginApi:
import { defineStore } from 'pinia'
import { loginApi } from '../api/login' // 新增
export const useProfileStore = defineStore('profile', {
state() {
return {
userName: '',
phone: '',
avatar: '', // 新增
}
},
actions: {
login(userName, password) { // 新增
loginApi(userName, password)
.then((res) => { // 登录成功以后,修改了用户名
this.userName = res.userName
})
.catch((err) => {
console.log(err)
})
},
},
})
最后我们在App.vue中调用login这个action:
用户名是: {{ profileStore.userName }}
手机号是: {{ profileStore.phone }}
页面上最终显示:
用户名是: 林哥
手机号是:
异步修改state并没有什么特殊,只是多调用了一个异步方法,修改时还是使用this就行了。这就比Vuex中方便不少。
使用$patch同时修改多个值
我们现在只更新了userName的值,我们还有phone和avatar两个值,可以这么写
this.userName = res.userName
this.phone = res.phone
this.avatar = res.avatar
也可以使用$patch方法,一次修改多个值:
this.$patch({
userName: res.userName,
phone: res.phone,
avatar: res.avatar,
})
页面上显示:
用户名是: 林哥
手机号是: 18888888888
这节课就到这里了,总结一下:
1)使用actions同步或者异步修改state
2)使用$patch可以一次修改多个值
ps:虽然pinia支持不通过action,直接修改state的值,但是我觉着统一在action中修改比较规范、合理。我看github上的讨论大部分人也都倾向不能随便state的值。所以这里只给大家介绍了在action中修改state的方式。