Pinia cheat sheet (Vue 3 version)

Initialize Pinia

import { createPinia } from 'pinia'

const pinia = createPinia()
pinia.use(SomePiniaPlugin) // 给 pinia 装插件

const app = createApp(App)
app.use(pinia)
// 这里需要注意时间顺序:只有在调用 app.use(pinia) 之后才能调用 useXxxStore()
复制代码

Use Store

  1. defineStore accepts an id, the id of different data sources must be different
  2. The return value of useCounter() cannot be destructured, which will result in the loss of data responsiveness
// src/stores/counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counterStore', {
  state: ()=> {
    return {j: 0, k: 0}
  }
})

// counter.js
import { useCounterStore } from 'path/to/src/stores/counterStore'

export default {
  setup() {
    const counterStore = useCounterStore()
    // 这里在视图里使用 counterStore.j 和 counterStore.k
    // 但你不能解构 counterStore,只能像下面这样解构:
    const { j, k } = storeToRefs(counterStore)	
    return {
      counterStore, j, k,
    }
  },
}
复制代码

Store Getters

Getters is actually a collection of computed properties of the store, and getters cannot be asynchronous functions

export const useStore = defineStore('main', {
  state: () => ({
    counter: 0,
  }),
  getters: {
    doubleCount(state) {
      return state.counter * 2
    },
    doublePlusOne(): number {
      return this.doubleCount + 1 // getter 访问另一个 getter 可以用 this
    },
    getUserById: (state) => { // getter 可以返回一个函数,不过这会导致缓存失效
      return (userId) => state.users.find((user) => user.id === userId)
    },
		otherGetter(state) { // 你还可以调用其他的 store
      const otherStore = useOtherStore()
      return state.localData + otherStore.data
    },
  },
})
// store.doubleCount 和 store.doublePlusOne 就可以直接当做属性使用了
// store.getUserById(userId) 可以当做函数使用
复制代码

Store Actions

Action is actually the methods of the store, and it can be an asynchronous function

export const useUserStore = defineStore('users', {
  state: () => ({
    userData: null,
  }),
  actions: {
    async signUp(email, password) {
      this.userData = await api.post({ email, password }).catch(error => {
        showError(error); throw error;
      })
    },
  },
})
// 然后你就可以使用 userStore.signUp(email, password) 了
复制代码

store.$patch(object | fn)

counterStore.$patch(
   {j: counterStore.j + 1, name: 'j加1'} 
)

cartStore.$patch((state) => {
  state.items.push({ name: 'shoes', quantity: 1 })
  state.hasChanged = true
})
复制代码

store.$subscribe(fn)

Used to monitor overall changes in state.

cartStore.$subscribe((mutation, state) => {
  // import { MutationType } from 'pinia'
  mutation.type // 'direct' | 'patch object' | 'patch function'
  mutation.storeId  
  mutation.payload // 获取 $patch 接收到的参数

  localStorage.setItem('cart', JSON.stringify(state))
})
复制代码

It has a very convenient feature that it will automatically log out when the component is unloaded. If you don't want it, you can pass an {detached: true}option .

You can also use watch to achieve a similar effect:

watch(
  pinia.state,
  (state) => {
    localStorage.setItem('piniaState', JSON.stringify(state))
  },
  { deep: true }
)
复制代码

store.$onAction()

Used to monitor the execution of all actions.

const unsubscribe = someStore.$onAction(
  ({
    name, // action 的名字
    store, // store === someStore
    args, // action 的实际参数
    after, // action 成功之后执行 after
    onError, // action 失败之后执行 onError
  }) => {
    const startTime = Date.now()
    console.log(`开始执行 "${name}" 参数为 [${args.join(', ')}].`)
    after((result) => {
      console.log(
        `执行成功 "${name}" 用时 ${Date.now() - startTime}毫秒\n结果为:${result}`
      )
    })
    onError((error) => {
      console.warn(
        `执行失败 "${name}" 用时 ${Date.now() - startTime}毫秒\n报错为:${error}.`
      )
    })
  }
)
// $onAction 会在它所在组件卸载时自动销毁
// 如果你将 $onAction 的第二个参数设置为 true,那么你需要自己调用 unsubscribe 来取消监听。
复制代码

store.$reset()

You can reset the state with counterStore.$reset()

store.$state

// 下面两句代码都能覆盖原有 state
store.$state = { counter: 666, name: 'Paimon' }
pinia.state.value = {} // 这句常用在 SSR
复制代码

Guess you like

Origin juejin.im/post/7083103819285921799
Recommended