跳至主要內容

Defining a Store

Zhao Bin笔记frontendpiniapinia

Defining a Store

A store is defined using defineStore() and that it requires a unique name, passed as the first argument:

import { defineStore } from 'pinia'

// useStore could be anything like useUser, useCart
// the first argument is a unique id of the store across your application
export const useStore = defineStore('main', {
  // other options
})

This name, also referred as id, is necessary and is used by Pinia to connect the store to the devtools.
Naming the returned function use... is a convention across composables to make its usage idiomatic.

Using a store

We are defining a store because the store won't be created until useStore() is called inside of setup():

import { useStore } from '@/store/counter'

export default {
  setup() {
    const store = useStore()

    return {
      // you can return the whole store instance to use it in the template
      store,
    }
  },
}

You can define as many stores as you want and you should define each store in a different file to get the most out of pinia (like automatically allow your bundle to code split and TypeScript inference).

Note that store is an object wrapped with reactive, meaning there is no need to write .value after getters but, like props in setup, we cannot destructure it:

export default defineComponent({
  setup() {
    const store = userStore()

    // ❌ This won't work because it breaks reactivity
    // it's the same as destructuring from `props`
    const { name, doubleCount } = store

    name // "eduardo"
    doubleCount // 2

    return {
      // will always be "eduardo"
      name,
      // will always be 2
      doubleCount,
      // this one will be reactive
      doubleValue: computed(() => store.doubleCount),
    }
  },
})
Destructure example

In order to extract properties from the store while keeping its reactivity, you need to use storeToRefs().
It will create refs for every reactive property.
Note you can destructure actions directly from the store as they are bound to the store itself too:

import { storeToRefs } from 'pinia'

export default defineComponent({
  setup() {
    const store = useStore()

    // `name` and `doubleCount` are reactive refs
    // This will also create refs for properties added by plugins
    // but skip any action or non reactive (non ref/reactive) property
    const { name, doubleCount } = storeToRefs(store)
    // the increment action can be just extracted
    const { increment } = store

    return {
      name,
      doubleCount,
      increment,
    }
  },
})
Destructure example using storeToRefs