本篇文章细说一下Vue全家桶中的Pinia,Pinia是官方指定的下一代Vuex,值得一探究竟。
Pinia的优势
和 Vuex
相比,Pinia
有许多优势:
取消了
Mutations
- 它本身就显得很多余
- 对
TypeScript
支持更好,Vuex
对于TS
的支持很不好 取消了
modules
的结构嵌套和命名空间的概念- 可以灵活的使用每一个
store
,它们通过扁平化的方式相互使用。
- 可以灵活的使用每一个
Pinia的安装和基本使用方法
- 安装Pinia的命令:
npm install pinia
在项目新建入口文件,具体路径为
src/stores/index.js
import { createPinia } from 'pinia' const pinia = createPinia() export default pinia
在
main.js
文件中挂载Pinia
import pinia from './stores' // 使用 use() 方法挂载 createApp().use(pinia)
定义
store
用于共享状态在
stores
文件夹中新建一个文件用于共享状态,具体路径为src/stores/aaa.js
import { defineStore } from 'pinia' // defineStore() 方法第一个参数是 Store 的名字 // 第二个参数是一个对象,定义共享状态 // defineStore() 返回的是一个函数 const useCounter = defineStore('counter', { state: () => ({ count: 11 }) }) // 导出 export default useCounter
使用
store
(composition API
的写法)在任意的组件中使用。
<script setup> // 导入Store import useCounter from '/src/stores/conuter.js' // 使用 store const counterStore = useCounter() </script> <template> <!-- 使用Store里面的值 --!> <h2>{{ counterStore.count }}</h2> <!-- 11 --!> </template>
Pinia中Store的解构
如果直接解构Store里面的参数,里面的参数就不是响应式的了,可以使用toRefs()
方法进行解构,Pinia也提供了一个方法storeToRefs
进行响应式的解构。
import { toRefs } from 'vue'
import { storeToRefs } from 'pinia'
const { count } = toRefs(counterStore)
const { count } = storeToRefs(counterStore)
Pinia中的State
State可以定义初始状态
修改State
在
Vuex
中需要使用mutations
修改state的值,在pinia
中取消了这一概念,允许直接修改值。import useCounter from 'xxx' const counterStore = useCounter() // 修改count的值 可以直接修改的 counterStore.count = 22
重置State
$reset()
方法可以重置state为初始值。const counterStore = useCounter() counter.$reset() // 重置为初始状态 11
一次性修改多个State
使用
$patch()
方法可以一次性修改多个值。const counterStore = useCounter() counterStore.$patch({ count: 33, price: 100 })
替换State
使用
$state
属性可以设置新的对象来替换 store 中整个 stateconst counterStore = useCounter() counterStore.$state = { count: 44, price: 200 }
Pinia中的Getters
Getters的功能类似于Computed计算属性。基本使用如下:
const useCount = defineStore('count', {
state: () => ({
count: 11
})
getters: {
// 默认传递一个 state 参数 用于操作state
increment(state) {
return state.count * 2
}
}
})
export default useCount
使用 Getters
<script setup>
import useCount from 'count.js'
const countStore = useCount()
</script>
<template>
{{ countStore.increment }}
</template>
一个getter使用另一个getter,在getter中是由this的,this指向的是当前store的实例
const useCount = defineStore('count', {
state: () => ({
count: 11
})
getters: {
// 默认传递一个 state 参数 用于操作state
increment(state) {
return state.count * 2
},
incrementAddOne() {
// this 是 store 实例
return this.increment +1
}
}
})
export default useCount
getter也支持返回一个函数。
getters: {
findSomeOne(state) {
return function(id) {
// 查找 id 相同的一项
state.Some.find(x => x.id === id)
}
}
}
getter使用其他 store 中的数据
// 在 count.js 中
// 导入别的 store
import useUser from 'user.js'
getters: {
getUserInfo () {
// 获取 userStore 的信息
const userStore = useUser()
// 返回 userStore 的用户信息
return `name: ${userStore.name}`
}
}
Pinia中的Actions
Actions适合定义业务逻辑,例如网络请求。action中访问state数据可以使用 this 访问。
defineStore('count', {
state: () => ({
count: 10
})
actions: {
increment(num) {
// num 是接收传递过来的参数的
// 使用this访问store实例
return this.count++
return this.count += num
}
}
})
使用Actions
<script setup>
import useCount from 'count.js'
function addClick() {
// 调用 actions 中的方法
useCount.increment()
// 调用时可以传递参数
useCount.increment(10)
}
</script>
Actions可以发起异步请求
actions: {
async getInfo() {
const res = await fetch('https://xxx')
// 将数据存到state的info中
this.info = res.data.info
}
}
Comments | NOTHING