如何使用pinia
安装
yarn add pinia
npm install pinia
引入+注册
main.js
import {createPinia} from 'pinia'
const pinia = createPinia()
const app = createApp(App)
app.use(pinia)
定义Store
userStore.ts
import { defineStore } from "pinia";
export const useUserStore = defineStore('user',{
//类似于vue的data
state:()=>{
return {
name:'xiaofan',
age:10,
}
},
//类似于vue的computed
getters:{
//可选参数:state
userInfo(state){
return `${state.name}今年${state.age}岁啦!!!`
},
//getter中使用this,必须指明函数的返回值类型,否则类型推断不出来
nextAge():number{
return this.age+1
}
},
/**
* 类似于vue的method
* 同步、异步都支持
*/
actions:{
changeUserName(value:string){
this.name = value
},
}
})
组件中展示数据
UserInfo.vue组件
<script lang="ts">
import { useUserStore } from '../stores/user';
export default{
setup(){
const userStore = useUserStore()
return {
userStore
}
}
}
</script>
<template>
<div>
<h1>姓名:{{userStore.name }}</h1>
<h1>年龄:{{ userStore.age }}</h1>
<h2>信息:{{ userStore.userInfo }}</h2>
</div>
</template>
<style >
</style>
修改数据
1、改单个数据
//template
<button @click="userStore.age++">长大一岁</button>
2、修改多个数据--$patch--参数对象模式
//template
<button @click="changeUser">修改多个数据</button>
//script
const changeUser = ()=>{
userStore.$patch({
name:'Jelly',
age:userStore.age+1
})
}
但是,使用这种语法应用某些突变非常困难或代价高昂:任何集合修改(例如,从数组中推送、删除、拼接元素)都需要您创建一个新集合。 正因为如此,$patch 方法也接受一个函数来批量修改集合内部分对象的情况:
3、修改多个数据--$patch--参数函数模式
//script
const changeUser1=()=>{
userStore.$patch((state)=>{
state.name = "Gillian"
state.age++
})
}
4、用action修改数据
//template
<button @click="userStore.changeUserName('Gillian')">修改数据--使用action</button>
解构store中的数据
因为pinia是把state数据做了reactive处理,所以直接解构会失去响应式,要解构出具备响应式的数据,需要借助storeToRefs
//template
<h1>直接解构出的数据name----{{ userName }}</h1>
<h1>stroreToRef解构出的数据-----{{ name }}</h1>
//script
let {name:userName} =userStore
let {name,age} = storeToRefs(userStore)
修改数据前
修改数据后
重置state为初始化数据---$reset
<button @click="userStore.$reset">重置state中的数据为初始化数据</button>
整个替换state数据---$state
//script
const changeState = ()=>{
userStore.$state={
name:'Gillian',
age:18,
}
}
//template
<button @click="changeState">整个修改state的数据</button>
订阅状态---$subscribe
setup(){
userStore.$subscribe((mutation,state)=>{
mutation.type // 'direct' | 'patch object' | 'patch function'
// 与 cartStore.$id 相同
mutation.storeId // 'cart'
console.log(mutation)
console.log(state)
//state数据变化后,你的操作---例如:更新本地存储
localStorage.setItem('user',JSON.stringify(state))
})
}
默认情况下,state subscriptions 绑定到添加它们的组件(如果 store 位于组件的 setup() 中)。 意思是,当组件被卸载时,它们将被自动删除。 如果要在卸载组件后保留它们,请将 { detached: true } 作为第二个参数传递给 detach 当前组件的 state subscription:
export default {
setup() {
const someStore = useSomeStore()
// 此订阅将在组件卸载后保留
someStore.$subscribe(callback, { detached: true })
// ...
},
}
订阅action及其结果---$onAction
const unsubscribe = userStore.$onAction(
({
name, // action 的名字
store, // store 实例
args, // 调用这个 action 的参数
after, // 在这个 action 执行完毕之后,执行这个函数
onError, // 在这个 action 抛出异常的时候,执行这个函数
})=>{
console.log('store',store)
const startTime = Date.now()
// 这将在 `store` 上的操作执行之前触发
console.log(`Start "${name}" with params [${args.join(', ')}].`)
// 如果 action 成功并且完全运行后,after 将触发。
// 它将等待任何返回的 promise
after((result) => {
console.log(
`Finished "${name}" after ${
Date.now() - startTime
}ms.\nResult: ${result}.`
)
})
// 如果 action 抛出或返回 Promise.reject ,onError 将触发
onError((error) => {
console.warn(
`Failed "${name}" after ${Date.now() - startTime}ms.\nError: ${error}.`
)
})
}
)
//手动取消action订阅
const cancelActionSubscrib = ()=>{
unsubscribe()
}
默认情况下,action* *subscriptions 绑定到添加它们的组件(如果 store 位于组件的 setup() 内)。 意思是,当组件被卸载时,它们将被自动删除。 如果要在卸载组件后保留它们,请将 true 作为第二个参数传递给当前组件的 detach action subscription:
export default {
setup() {
const someStore = useSomeStore()
// 此订阅将在组件卸载后保留
someStore.$onAction(callback, true)
// ...
},
}
getter有缓存
<h2>信息:{{ userStore.userInfo }}</h2>
<h2>信息:{{ userStore.userInfo }}</h2>
<h2>信息:{{ userStore.userInfo }}</h2>
getters:{
userInfo(state){
console.log('计算了userInfo')
return `${state.name}今年${state.age}岁啦!!!`
},
},
只输出了一次