订阅状态及方法

订阅 state

类似于 Vuex 的 subscribe 方法,你可以通过 store 的 $subscribe() 方法侦听 state 及其变化。

<script setup>
import { storeToRefs } from 'pinia'
import { useCounterStore } from '/src/store/store'
const store = useCounterStore()
const { count } = storeToRefs(store)
const add = function(){
  console.log(count.value);
  store.count++;
}
// 订阅 state
store.$subscribe((mutation, state) => {
  console.log(mutation);
  console.log(state);
});
</script>
<template>
  <div>
    <div>数值 : {{ count }}</div>
    <div>数值 : {{ store.doubleCount }}</div>
    <div>
      <button @click="add">+ 1</button>
      <button @click="store.randomizeCounter()">随机</button>
    </div>
  </div>
</template>
<style scoped>
</style>

订阅 action

可以通过 store.$onAction() 来监听 action 和它们的结果。传递给它的回调函数会在 action 本身之前执行。after 表示在 promise 解决之后,允许你在 action 解决后执行一个一个回调函数。同样地,onError 允许你在 action 抛出错误或 reject 时执行一个回调函数。这些函数对于追踪运行时错误非常有用,类似于Vue docs 中的这个提示。

定义演示

import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter',{
  state : ()=>{
    return {
      count : 0
    }
  },
  getters : {
    doubleCount : (state)=>{
      return state.count +  2;
    }
  },
  actions : {
    // 类似 getter,action 也可通过 this 访问整个 store 实例,
    // 不同的是,action 可以是异步的,你可以在它们里面 await 调用任何 API,以及其他 action!
    randomizeCounter : function(){
      this.count = Math.round(100 * Math.random())
      return this.count;
    }
  }
})

监听演示

<script setup>
import { storeToRefs } from 'pinia'
import { useCounterStore } from '/src/store/store'
const store = useCounterStore()
const { count } = storeToRefs(store)
const add = function(){
  console.log(count.value);
  store.count++;
}
// 订阅 state
store.$subscribe((mutation, state) => {
  console.log(mutation);
  console.log(state);
});
//
store.$onAction(
  ({
    name, // action 名称
    store, // store 实例,类似 `someStore`
    args, // 传递给 action 的参数数组
    after, // 在 action 返回或解决后的钩子
    onError, // action 抛出或拒绝的钩子
  }) => {
    console.log(name);
    console.log(after);

    // 这将在 action 成功并完全运行后触发。
    // 它等待着任何返回的 promise
    after((result) => {
      console.log(
        `Finished "${name}" after ${
          Date.now()
        }.\nResult: ${result}.`
      )
    })
  })
</script>
<template>
  <div>
    <div>数值 : {{ count }}</div>
    <div>数值 : {{ store.doubleCount }}</div>
    <div>
      <button @click="add">+ 1</button>
      <button @click="store.randomizeCounter()">随机</button>
    </div>
  </div>
</template>
<style scoped>
</style>