一文带你搞懂Vue3中Pinia的使用
作者:BDawn
什么是Pinia
用官网的一句话来说:Pinia 是 Vue的专属状态管理库
Pinia就是为vue3而生,当然也支持vue2
Pinia VS Vuex
Pinia在使用上更简单,更适合同组合式api和Typescript一同使用
安装Pinia
npm install pinia # or yarn add pinia
在vue的main.js中使用
import { createApp } from 'vue'
import App from './App.vue'
import {createPinia} from "pinia";
const app = createApp(App)
app.use(createPinia())
app.mount('#app')
使用Pinia
定义store
store通过defineStore()函数进行定义,可以定义多个store,但是定义每个store的时候必须要传入一个唯一的id作为defineStore()的第一个参数
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({ user: {
name: '张三'
} }),
getters: {
userName: (state) => state.user.name,
},
actions: {
setName(name) {
this.user.name = name
},
},
})
也可以定义组合式api形式的store
ref()对应 state
- computed() 对应 getters
- function() 对应 actions
export const useUserStore = defineStore('user', () => {
const user = ref({
name: '张三'
})
const userName = computed(() => {
return user.value.name
})
function setName(name) {
user.value.name = name
}
return { user, userName, setName }
})在vue组件中使用store
<template>
<div>
<div>用户名: {{userName}}</div>
<button @click="handleClick">设置用户名</button>
</div>
</template>
<script lang="ts" setup>
import {useUserStore} from "../stores";
import {storeToRefs} from "pinia";
const store = useUserStore()
// 将store中的state或者getter转为响应式变量
const {userName} = storeToRefs(store)
// 将store中的action解构出来
const {setName} = store
const handleClick = () => {
increment('李四')
}
</script>
<style scoped lang="scss">
</style>
Pinia之state
state在store里面是一个返回初始状态的函数
import { defineStore } from 'pinia'
interface User {
name: string
sex: number
}
const useUserStore = defineStore('user', {
// 如果使用的是ts,使用箭头函数可以自动推理出state返回状态的类型
state: () => {
return {
isTest: false
count: 1,
userList: [] as User[],
}
},
})访问state
const store = useUserStore() store.count++
重置store中的state
调用$reset()重置之后,state里的状态会全部恢复为初始值
store.$reset()
修改state中的状态
除了上面store.count++直接修改这种方式,还可以使用$patch函数同时修改多个状态
store.$patch({
count: store.count + 1,
isTest: true,
})
// 传入一个函数
store.$patch((state) => {
state.count = state.count + 1,
state.isTest = true
})
订阅state
通过store的$subscribe函数可以监听state 的变化
store.$subscribe((mutation, state) => {
console.log(mutation);
console.log(state);
})
mutation为修改state的方式,主要有三个属性
1.type: direct | patch object | patch function
- direct:通过等号直接赋值的方式修改state的状态时
- patch object :通过$patch函数修改并且传入的参数为一个对象时
- patch function:通过$patch函数修改并且传入的参数为一个函数时
2.storeId:定义当前store时传入的唯一id
3.payload:type为patch object 时,传入的对象
Pinia之getter
getter完全等同于store中state的计算属性,推荐使用箭头函数来定义getter,并将state作为第一个参数。
在getter内部可以通过this方位到整个store
定义getter
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({ user: {
name: '张三'
} }),
getters: {
userName: (state) => state.user.name,
},
})
组合式api的形式定义getter
export const useUserStore = defineStore('user', () => {
const user = ref({
name: '张三'
})
// 相当于getter中定义userName
const userName = computed(() => {
return user.value.name
})
return { user, userName }
})
向getter传参
访问getter时不能传递任何参数,但是可以通过使getter返回一个接收参数的函数的形式来接收参数
getters: {
userName: (state) => {
return (before) => before + state.user.name
},
}
访问带参getter
<script>
export default {
setup() {
const store = useUserStore()
return { getUserName: store.userName }
},
}
</script>
<template>
<p>{{ getUserName('Hi,') }}</p>
</template>
Pinia之action
action相当于组件的method,在store中定位为一个函数(可以是异步函数),主要用于处理业务逻辑,在action内部同样可以通过this访问的整个store的属性
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({ user: {
name: '张三'
} }),
actions: {
setName(name) {
this.user.name = name
},
},
})
访问action
export default {
setup() {
const store = useUserStore()
store.setName('李四')
return { }
},
}
订阅action
通过store的$onAction()函数来监听action执行的相关信息.
$onAction()接收两个参数,第一个参数为一个钩子函数,会在action执行之前调用此钩子函数;第二个参数是一个boolean类型的参数,当前组件被销毁是传入的钩子函数是否继续执行,默认为false
const store = useUserStore()
store.$onAction(({name, store, args, after, onError})=>{
console.log(`${name} 函数准备开始执行`)
console.log(`${name} 函数的参数为:${args}`)
after(() => {
console.log(`${name} 函数执行完成`)
})
})
// 手动删除监听器
unsubscribe()到此这篇关于一文带你搞懂Vue3中Pinia的使用的文章就介绍到这了,更多相关Vue3 Pinia内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
