Pinia

669 阅读1分钟

挂载

import { createApp } from "vue";
import App from "./App.vue";
import {createPinia} from 'pinia'
const pinia = createPinia()
createApp(App).use(pinia).mount("#app");

创建store

import { defineStore } from "pinia";

export const storeA = defineStore("storeA", {
  state: () => {
    return {
      piniaMsg: "hello pinia",
      name:"111"
    };
  },
  getters: {},
  actions: {
    setName(data){
      this.name = data
    }
  },
});

获取状态,修改状态,重置状态

<template>
  <div></div>
</template>
<script setup>
import { storeA } from '@/piniaStore/storeA'
let piniaStoreA = storeA()
//获取状态
console.log(piniaStoreA.piniaMsg); //hello pinia
//直接修改状态
piniaStoreA.piniaMsg = 'hello juejin'
//批量修改状态
piniaStoreA.$patch({
  piniaMsg: 'hello juejin',
  name: 'daming'
})
//通过action修改状态
piniaStoreA.setName('daming')
//重置状态
piniaStoreA.$reset()
</script>

解构

当我们组件中需要用到state中多个参数时,使用解构的方式取值往往是很方便的,但是传统的ES6解构会使state失去响应式,为了解决这个问题,Pinia提供了一个结构方法storeToRefs

<template>
  <div>{{ name }}</div>
</template>

<script setup>
import { storeA } from '@/piniaStore/storeA'
import { storeToRefs } from 'pinia'
let piniaStoreA = storeA()
let { piniaMsg, name } = storeToRefs(piniaStoreA)
piniaStoreA.$patch({
  name: 'daming'
})
</script>

getters

Vuex中的getters和Pinia中的getters用法是一致的,用于自动监听对应state的变化,从而动态计算返回值(和vue中的计算属性差不多),并且getters的值也具有缓存特性

getters得第一个参数是state对象

import {defineStore} from 'pinia'

export default defineStore('storeA',{
  state:()=>{
    return {
      piniaMsg:'test',
      name:'11',
      a:1,
      b:4
    }
  },
  getters:{
    c(state){
      return state.a+state.b
    }
  },
  actions:{
    setMsg(data:string){
      this.piniaMsg = data
    }
  }
})

getters中的this

getter中同样可以使用 this,但是 TS 无法推导类型,需要手动指定返回值类型:

import {defineStore} from 'pinia'

export default defineStore('storeA',{
  state:()=>{
    return {
      a:1,
      b:4
    }
  },
  getters:{
    c():number{
      return this.a+this.b
    },
  },
})

将参数传递给getters

可以从 getter 返回一个函数来接受任何参数,请注意,执行此操作时,getter 不再缓存

import {defineStore} from 'pinia'

export default defineStore('storeA',{
  state:()=>{
    return {
      a:1,
    }
  },
  getters:{
    d():Function{
      return (num:number):number=>{
        return this.a + num
      }
    }
  },
})

//外部调用
<script lang="ts">
import storeA from '@/pinia/storeA'
import {storeToRefs} from 'pinia'
export default defineComponent({
  name: "App",
  setup() {
    const piniaStoreA = storeA()
    let {piniaMsg,a,c,d} = storeToRefs(piniaStoreA)
    let gettersD = d.value(9)
    return {
      a,
      gettersD
    };
  },
});
</script>

modules

Pinia没有modules,如果想使用多个store,直接定义多个store传入不同的id即可

import { defineStore } from "pinia";

export const storeA = defineStore("storeA", {...});
export const storeB = defineStore("storeB", {...});
export const storeC = defineStore("storeB", {...});

状态持久化

使用pinia-plugin-persist持久化状态管理插件,它会默认把你需要持久化的数据缓存在Session Storage里

第一步:安装pinia-plugin-persist插件
npm i pinia-plugin-persist --save

第二步:在你需要缓存的store 里开启 persist 
export const useUserStore = defineStore({
  id: 'user',
  state: () => {
    return {
      name: '张三'
    }
  },
  // 开启数据缓存
  persist: {
    enabled: true
  }
})

默认所有 state 都会进行缓存,你可以通过 paths 指定要持久化的字段,其他的则不会进行持久化

可以在 strategies 里自定义 key 值,并将存放位置由 sessionStorage 改为 localStorage

state: () => {
  return {
    name: '张三',
    age: 18,
    gender: '男'
  }  
},

persist: {
  enabled: true,
  strategies: [
    {
      key: 'my_user',
      storage: localStorage,
      paths: ['name', 'age']
    }
  ]
}

vuex与pinia

1、pinia没有了mutations和modules,同步异步操作均可在actions中进行

2、vuex修改状态时在mutations中修改,外部可直接commit,也可在action中commit,外部dispatch此action,pinia可以直接在外部修改状态,通过patch函数科批量修改状态,也可在action中修改,外部直接调用action即可,pinia通过patch函数科批量修改状态,也可在action中修改,外部直接调用action即可,pinia通过reset函数可充值初始值