前段时间看见官网说vue2官网文档将会停止更新,这意味着vue3将会作为工作中的开发主流。在使用vue3中,vue3引入了ts,随之更改的配套有element ui更改为了element plus。开发了一段时间之后,发现vuex出现了一个新的替代者(pinia)。下面是我阅读文档顺便做的记录,仅供参考。
与vuex的区别
- 更简单的规范,提供了一个Composition API风格的API
- 与ts结合更具备可靠的类型推断
- 使用上:(Pinia API 与 Vuex ≤4 有很大不同)
1) mutations不再存在
2)不再有 modules 的嵌套结构
3)没有 命名空间模块
4)可以直接对store中state数据进行赋值操作。
pinia的使用方法
- 定义store
官网中提供defineStore()来定义,并且需要给予store一个唯一的名称
import { defineStore } from 'pinia'
// useStore 可以是 useUser、useCart 之类的任何东西
// 第一个参数是应用程序中 store 的唯一 id
export const useStore = defineStore('main', {
// other options... 此处定义store的内容state,getters,actions
})
书写方法:由于pinia中已经没有modules的概念,编写的时候,根据实际需求,需要多少个store就写多少个store文件
- state
1)对象定义格式(类似于vue2中data的定义方式)
//写法一
state: () => {
return {
counter: 0,
name: 'Eduardo',
isAdmin: true,
}
}
//写法2
state: () => ({
//内容
})
2)在组件中使用时,对state的访问及更改
//直接修改
storeName.counter++ 或者 storeName.name="小王"
//$patch (正对于state的批量修改)
* 对象修改法
store.$patch({
counter: store.counter + 1,
name: 'Abalam',
})
注意:此处的store指的是引入文件时,store的命名
缺点:这种方式若只修改counter一个属性,但是却需要附带其余所有其他属性(不需要修改的),修改代价比较大
* 函数修改法(哪些需要修改就写哪些)
cartStore.$patch((state) => {
state.items.push({ name: 'shoes', quantity: 1 })
state.hasChanged = true
})
//整个state替换(运用场景较少)
store.$state = { counter: 666, name: 'Paimon' }
//state初始值重置功能
storeName.$reset()
- getters
1.定义格式
getters: {
doubleCount: (state) => state.counter * 2,
}
2.可以访问this
在定义中可用this访问到store实例
doublePlusOne(): number {
return this.counter * 2 + 1
}
注意:
* 使用this时,不可以用箭头函数定义,箭头函数中使用this,this指向会变更
* 函数中this访问时,在ts文件中,必须明确返回类型
3.如何传递参数(返回函数)
getters如同computed计算属性,若想接收参数,可以返回一个函数
//定义
getters: {
getUserById: (state) => {
return (userId) => state.users.find((user) => user.id === userId)
},
}
//页面使用
storeName.getUserById(1) //传参
storeName.doubleCountPlusOne //无传参定义时的访问
- actions
//类似于methods,主要用于业务逻辑的定义
//可以是同步,也可以是异步
actions: {
increment() {
this.counter++
},
randomizeCounter() {
this.counter = Math.round(100 * Math.random())
},
//异步
async registerUser(login, password) {
this.userData = await api.post({ login, password })
}
},
}
//页面调用
storeName.randomizeCounter()
特殊补充:
pinia中定义的state,实际就是使用vue3中reactive定义的一个对象,页面中访问的时候,若直接对它进行结构,会丧失响应式的功能,如下效果:
//以下作为错误示范(会造成响应式丢失)
let { count, price } = storeCounter;
效果:若store.count中途改变数值,此处的count不会随之改变
//解决办法:storeToRefs
let { count, price } = storeToRefs(storeCounter); //为所有属性添加响应式refs
使用时:
count.value来访问值