Pinia使用说明Vue3状态管理组件

本文参考:https://blog.csdn.net/qq1195566313/article/details/123338137

https://pinia.web3doc.top/
状态管理组件,代替vuex
Pinia使用说明Vue3状态管理组件_第1张图片

_Pinia.js 有如下特点:_

  • 完整的 ts 的支持;
  • 足够轻量,压缩后的体积只有1kb左右;
  • 去除 mutations,只有 state,getters,actions;
  • actions 支持同步和异步;
  • 代码扁平化没有模块嵌套,只有 store 的概念,store 之间可以自由使用,每一个store都是独立的
  • 无需手动添加 store,store 一旦创建便会自动添加;
  • 支持Vue3 和 Vue2

安装

安装命令:
yarn add pinia
注册:
vue3在main.js中

import {createApp} from 'vue'
import App from './App.vue'
import {createPinia} from "pinia";

//引入pinia
const store = createPinia()

let app = createApp(App)

app.use(store).mount('#app')

vue2使用


import { createPinia, PiniaVuePlugin } from 'pinia'
 
Vue.use(PiniaVuePlugin)
const pinia = createPinia()
 
new Vue({
  el: '#app',
  // other options...
  // ...
  // note the same `pinia` instance can be used across multiple Vue apps on
  // the same page
  pinia,
})

创建仓库

Pinia使用说明Vue3状态管理组件_第2张图片
定义仓库defineStore,第一个值为仓库id

import {defineStore} from "pinia";
import {Names} from "./store-name";

export const useTestStore = defineStore(Names.TEST,{
  
    state:()=>{
        return{
            name:'zhouzhou',
            age:22
        }
    },
    //computed 有缓存,修饰一些值
    getters:{

    },
    //methods 可以同步也可以异步 提交state
    actions:{

    }


})
export const enum Names {
    TEST = 'TEST'
}

state

pinia修改状态一共有五种方式:
导入方式 :import {useTestStore} from ‘…/store’
const Test = useTestStore()
Test.name就可以取到值







最后一种定义actions
在action中不能写箭头函数,需要通过this来获取state中的值
Pinia使用说明Vue3状态管理组件_第3张图片
image.png

解构

和reactive一样,解构会丢失响应式
Pinia使用说明Vue3状态管理组件_第4张图片
解决方案:pinia提供了API:storeToRefs,解构完成之后,为Ref,修改值需要通过current.value++这样的形式
Pinia使用说明Vue3状态管理组件_第5张图片

actions

传参
Pinia使用说明Vue3状态管理组件_第6张图片
相互调用
Pinia使用说明Vue3状态管理组件_第7张图片

类似于method,可以在里面写同步以及异步代码

import {defineStore} from "pinia";
import {Names} from "./store-name";

type User = {
  name:string
  age:number
}

const login = ():Promise<User> => {
  return new Promise<User>((resolve, reject) => {
    setTimeout(() => {
      resolve({
        name:'qqqqq',
        age:32
      })
    },2000)
  })
}

export const useTestStore = defineStore(Names.TEST, {
  state: () => {
    return {
      user:{
        name: 'zhouzhou',
        age: 22
      }
    }
  },
  //computed 修饰一些值
  getters: {},
  //methods 可以同步也可以异步
  actions: {
    setName() {
      this.user.name = 'qiqi'
    },
    async setUser(){
      const result = await login()
      this.user = result
      console.log('fasdf');
    }
  }
  
  
})

getter

Pinia使用说明Vue3状态管理组件_第8张图片

image.png
相互调用
Pinia使用说明Vue3状态管理组件_第9张图片

API

https://blog.csdn.net/qq1195566313/article/details/123402377

$reset

重新恢复初始状态
在actions中
Pinia使用说明Vue3状态管理组件_第10张图片

$subscribe

当state中的值发生改变会调用
image.png
Pinia使用说明Vue3状态管理组件_第11张图片
更多参数:类似与watchEffect
Pinia使用说明Vue3状态管理组件_第12张图片

$onAction

Pinia使用说明Vue3状态管理组件_第13张图片
Pinia使用说明Vue3状态管理组件_第14张图片
after 和 watchEffect中的before很像,接收一个工厂函数,在$onAction的代码执行完之后调用
Pinia使用说明Vue3状态管理组件_第15张图片
第二个参数,布尔值,当为true的时候,组件实例销毁后onAction依然存活
Pinia使用说明Vue3状态管理组件_第16张图片

pinia持久化

pinia和vuex都有一个共同的问题:当刷新页面之后,数据就消失了(恢复原始数据,之前的操作不会保留)

手写持久化

使用pinia插件(main.js)
Pinia使用说明Vue3状态管理组件_第17张图片

返回值:
Pinia使用说明Vue3状态管理组件_第18张图片
总之我们要实现这个插件我们需要每次修改值就给它存起来

pinia-plugin.ts

import {createPinia, PiniaPluginContext} from "pinia";

//引入pinia
export const store = createPinia()

type Options = {
    key?: string
}
//如果use.store(piniaPlugin)这样,没有传参数,就使用这个值作为key
const __piniaKey__: string = 'zhoubao'

//设置缓存的方法
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) : {}
}

//pinia插件
//函数柯里化,概念看不太懂
//我们如果不使用这个技术,那么我们每次使用这个函数,就必须传入两个参数,但是我们发现,第二个参数都是一样的context: PiniaPluginContext
//所以我们希望这个函数只需要有一个参数,就是key,如果我们返回一个函数,而这个函数的形参为context: PiniaPluginContext
//那么我们发现,我们这个函数只需要传入一个参数就可以了


export const piniaPlugin = (options: Options) => {

    return (context: PiniaPluginContext) => {
        //context中是当前pinia的实例,我们通过解构的方式来获取其中我们需要存储的部分,也就是store
        const {store} = context
        
        //获取缓存中存储的store数据
        const data = getStorage(`${options?.key ?? __piniaKey__}-${store.$id}`)
        
        //pinia的api,当state中数据改变的时候,就设置缓存,设置缓存的时候需要toRaw方法(将refImpl对象转化为普通对象)才能正确放进去
        store.$subscribe(() => {
            setStorage(`${options?.key ?? __piniaKey__}-${store.$id}`, toRaw(store.$state))
        })
        
        //返回缓存中的数据,将store中的数据设置为缓存的数据
        return {
            ...data
        }
    }
}

如果将pinia-plugin.ts中的代码全部放在main.ts中,代码太多了,不太行,我们将它分解出来,放在pinia-plugin.ts里面,暴露store对象以及piniaPlugin方法,最后再main.ts中使用store身上的use方法将piniaPlugin方法加载上去即可

main.ts
Pinia使用说明Vue3状态管理组件_第19张图片

pinia持久化插件

npm安装 npm i pinia-plugin-persistedstate
vue3中使用:

import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
import {createPinia} from "pinia";

//使用pinia数据持久化
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)

createApp(App).use(ElementPlus).use(router).use(pinia).mount('#app')

使用方法

    getters:{},
    //    持久化
    persist:{
        key:'terminal-config-store',
        storage:window.localStorage,
        beforeRestore:()=>{
            console.log("load terminalConfigStore data start");
        },
        afterRestore:()=>{
            console.log("load terminalConfigStore data end")
        }
    },

你可能感兴趣的:(vue.js,javascript,前端)