vue3 状态管理工具 pinia,快速上手指南

495 阅读1分钟

QQ20220521-115936.png

Pinia是一个全新的Vue状态管理库,由 Vue.js团队中成员所开发的,因此也被认为是下一代的 Vuex。同时是 vue 作者尤雨溪强势推荐的 vue3 状态管理工具,小伙伴们赶紧学起来吧。

一、安装

yarn add pinia

二、使用

首先我们需要在项目的 main.js 中使用创建并使用 pinia

import { createPinia } from 'pinia'

app.use(createPinia())

三、定义一个 Store

像 vuex 一样,我们需要在项目里定义一个 store 仓库

import { defineStore } from 'pinia'

// main 是应用程序中 store 的唯一 id
export default defineStore('main', {
  state: () => {},
  getters: {},
  actions: {}
})

使用 store

<script setup>
  // storeToRefs 可以让 state 里的属性保持响应式
  import { storeToRefs } from 'pinia'

  import useMainStore from '@/stores/index'
  const mainStore = useMainStore()
  
  // 这里直接解构出来使用
  const { count } = storeToRefs(mainStore)

</script>

<template>
  <p>{{ count }}</p>
</template>

<style>
</style>

四、State

访问 state

默认情况下,可以通过 store 实例访问状态来直接读取和写入状态

<script setup>
  import useMainStore from '@/stores/index'
  const mainStore = useMainStore()
  
  // 通过 mainStore 直接可以访问里面的状态
  console.log(mainStore.count)
</script>

重置状态

<script setup>
  import useMainStore from '@/stores/index'
  const mainStore = useMainStore()
  mainStore.$reset()
</script>

改变状态

直接修改

<script setup>
  import useMainStore from '@/stores/index'
  const mainStore = useMainStore()
  mainStore.count++
</script>

通过 $patch 对象 修改

<script setup>
  import useMainStore from '@/stores/index'
  const mainStore = useMainStore()
  mainStore.$patch({
    count: mainStore.count + 1
  })
</script>

通过 $patch 函数 修改

<script setup>
  import useMainStore from '@/stores/index'
  const mainStore = useMainStore()
  mainStore.$patch(state => {
    state.count++
  })
</script>

替代 state

您可以通过 $state 属性设置新对象来替换 Store 的整个状态

<script setup>
  import useMainStore from '@/stores/index'
  const mainStore = useMainStore()
  mainStore.$state = { a: 1, b: 2 }
</script>

也可以通过更改 pinia 实例的 state 来替换应用程序的整个状态。

import { createPinia } from 'pinia'
const pinia = createPinia()

// 替换整个应用程序的状态
pinia.state.value = {}

app.use(pinia)

订阅状态

在 pinia 中我们可以通过 $subscribe()来查看状态及其变化

<script setup>
  import useMainStore from '@/stores/index'
  const mainStore = useMainStore()
  mainStore.$subscribe((mutation, state) => {
    // mutation 触发类型 ( 'direct' | 'patch object' | 'patch function' )
    console.log(mutation);
    // state 就是 store 的状态
    console.log(state);
  })
</script>

默认情况下,state subscriptions 绑定到添加它们的组件,当组件被卸载时,它们将被自动删除。 如果要在卸载组件后保留它们,请将 { detached: true } 作为第二个参数传递给 detach 当前组件的 state subscription

Getters

getter 完全等同于 store 状态的计算值

定义 getters

export default defineStore('main', {
  ...,
  getters: {
    getCount: state => state.count + 10
  }
})

访问 getters

<script setup>
  import useMainStore from '@/stores/index'
  const mainStore = useMainStore()
 
  console.log(mainStore.getCount)
</script>

Actions

actions 相当于组件中的methods

定义 actions

import { defineStore } from 'pinia'

export default defineStore('main', {
  ...,
  actions: {
    test() {
      this.count++
    }
  }
})

使用 actions

 <script setup>
  import useMainStore from '@/stores/index'
  const mainStore = useMainStore()

  // 调用 actions
  mainStore.test()
</script>

订阅 actions

可以使用 $onAction()订阅 action 及其结果。after 处理 Promise 并允许您在 action 完成后执行函数。onError 允许您在处理中抛出错误。

 <script setup>
  import useMainStore from '@/stores/index'
  const mainStore = useMainStore()

  const unsubscribe = mainStore.$onAction(
  ({
    name, // action 的名字
    store, // store 实例
    args, // 调用这个 action 的参数
    after, // 在这个 action 执行完毕之后,执行这个函数
    onError, // 在这个 action 抛出异常的时候,执行这个函数
  }) => {
    // 如果 action 成功并且完全运行后,after 将触发。
    // 它将等待任何返回的 promise
    after((result) => {
      
    })

    // 如果 action 抛出或返回 Promise.reject ,onError 将触发
    onError((error) => {
  
    })
  }
)

// 手动移除订阅
unsubscribe()
  
</script>

默认情况下,action subscriptions 绑定到添加它们的组件,当组件被卸载时,它们将被自动删除。 如果要在卸载组件后保留它们,请将 true 作为第二个参数传递给当前组件的 detach action subscription

 <script setup>
  import useMainStore from '@/stores/index'
  const mainStore = useMainStore()

  // 此订阅将在组件卸载后保留
  const unsubscribe = mainStore.$onAction(callback, true)
</script>