Pinan特点
- 支持TS
- 轻量,压缩后的体积只有1Kb左右
- 去除mutations,只有state,getters,actions
- actions支持同步和异步
- 支持Vue2和Vue3
安装
npm install pinia
引用(main.ts)
import { createPinia } from "pinia"
import { PiniaVuePlugin } from "pinia"
const store = createPinia()
app.use(store)
使用(src/store/index.ts)
import { defineStore } from "pinia"
import { Names } from './store-name'
export const useTestStore = defineStore(Names.TEST,{
state:()=>{
return {
count: 1,
name: "栗子"
}
},
getters: {
},
actions: {
setCount(num: number){
this.count = num
}
}
})
目录:src/store/store-name.ts
export const enum Names {
TEST = 'TEST'
}
在页面中使用(App.vue)
<template>
<div>{{ Test.count }}</div>
<div>{{ Test.name }}</div>
<button @click="change">修改state的值</button>
</template>
import { useTestStore } from "./store"
const Test = useTestStore()
state详解(5种方式修改state的值)
- 直接修改state的值
const change = ()=>{
Test.count++
}
- $patch(可批量修改)---对象
const change = ()=>{
Test.$patch({
count: 666,
name: "小栗子"
})
}
- $patch(可先处逻辑后修改值)---函数
const change = ()=>{
Test.$patch((state)=>{
state.count = 1314
state.name = "追光的栗子"
})
}
- $state(要修改必须覆盖整个对象)
const change = ()=>{
Test.$state = {
count: 333,
name: "炒栗子"
}
}
- 借助action去修改
const change = ()=>{
Test.setCount(9999)
}
解构store
import { useTestStore } from "./store"
import { storeToRefs } from "pinia"
const Test = useTestStore()
const { count,name } = storeToRefs(Test)
const change = ()=>{
count.value++
}
actions详解
- 可以进行同步或异步操作
- actions中两个方法也可以相互调用
目录:src/store/index.ts
type User = {
name: string,
age: number
}
let result: User = {
name: "栗子",
age: 18
}
const getList = ():Promise<User> =>{
return new Promise((resolve)=>{
setTimeout(()=>{
resolve({
name: "栗子",
age: 18
})
},3000)
})
}
export const useTestStore = defineStore(Names.TEST,{
state:()=>{
return{
user: <User>{},
user2: "",
name: "栗子"
}
}
actions: {
setUser(){
this.user = result
},
async getSetList(){
const res = await getList()
this.user2 = res
this.setName("追光的栗子")
},
setName(name: string){
this.name = name
}
}
})
在页面中使用(App.vue)
<template>
<div>{{ Test.user }}</div>
<div>{{ Test.user2 }}</div>
<button @click="change">change</button>
</template>
import { useTestStore } from "./store"
const Test = useTestStore()
const change = ()=>{
Test.setUser()
Test.getSetList()
}
getters详解
export const useTestStore = defineStore(Names.TEST,{
state:()=>{
return{
name: "栗子",
age: 18
}
},
getters:{
filueName(): string {
return `${this.name}----${this.getAge}`
}
getAge(): number {
return `${this.age}`
}
}
})
在页面中使用(App.vue)
<template>
<div>{{ Test.filueName }}</div>
</template>
import { useTestStore } from "./store"
const Test = useTestStore()
Pinia中的API
- $reset(重置state的值到初始状态)
<template>
<button @click="reset">使用$reset</button>
</template>
import { useTestStore } from "./store"
const Test = useTestStore()
const reset = ()=>{
Test.$reset()
}
- $subscribe(只要state中的值发生变化都会触发这个函数)
import { useTestStore } from "./store"
const Test = useTestStore()
Test.$subscribe((args,state)=>{
},{
detached: true,
deep: true,
flush: "post"
})
- $onAction(调用action中的方法触发)
import { useTestStore } from "./store"
const Test = useTestStore()
Test.$onAction((args)=>{
args.after(()=>{
})
},true)
Pinia插件的使用
- 问题:页面刷新数据会丢失
- 解决:封装插件维持数据持久化
import { createPinia, PiniaPluginContext } from "pinia"
type Options = {
key?: string
}
const _piniaKey: string = "栗子"
const setStorage = (key: string,value: any)=>{
localStorage.setItem(key,JSON.stringify(value))
}
const getStorage = (key: string)=>{
return localStorage.getItem(key) ? JSON.parse(localStorage.getItem(key) as string : {}
}
const piniaPlugin = (options: Options)=>{
return (context: PiniaPluginContext)=>{
const { store } = context
const data = getStorage(`${options?.key ?? _piniaKey}-${store.$id}`)
store.$subscribe(()=>{
setStorage(`${options?.key ?? _piniaKey}-${store.$id}`,toRaw(store.$state))
})
return {
...data
}
}
}
const store = createPinia()
store.use(piniaPlugin({
key: "pinia"
}))
app.use(store)