2023-04-21 | 使用指南 | UNLOCK | 更新时间:2023-4-21 11:3

Pinia的数据存储及遇到的问题

安装

yarn add pinia || npm install pinia

示例

在项目中,需要配置后才可以使用

stores/counter.js
import { defineStore } from 'pinia' export const useCounterStore = defineStore('counter', { state: () => { return { count: 0 } }, // 也可以这样定义 // state: () => ({ count: 0 }) actions: { increment() { this.count++ }, }, })
vite.config.js
// ... AutoImport({ //... dirs: [ 'src/stores', ], }),

组件中的使用

Hello.vue
<script setup> import { useCounterStore } from '@/stores/counter' const counter = useCounterStore() counter.count++ // 自动补全! ✨ counter.$patch({ count: counter.count + 1 }) // 或使用 action 代替 counter.increment() </script> <template> <!-- 直接从 store 中访问 state --> <div>Current Count: {{ counter.count }}</div> </template>

Store

defineStore

Store 是用 defineStore() 定义的,它的第一个参数要求是一个独一无二的名字

 import { defineStore } from 'pinia'

// 你可以对 `defineStore()` 的返回值进行任意命名,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。(比如 `useUserStore`,`useCartStore`,`useProductStore`)
// 第一个参数是你的应用中 Store 的唯一 ID。
export const useAlertsStore = defineStore('alerts', {
  state: () => ({ count: 0 }),
  getters: {
    double: (state) => state.count * 2,
  },
  actions: {
    increment() {
      this.count++
    },
  },
})

export const useAlertsStore = defineStore('alerts', ()=>{
  // setup语法
})

可以使用Setup语法,也可以使用配置语法,推荐配置语法,setup会让SSR变得更复杂。

state

import { defineStore } from 'pinia'

const useStore = defineStore('storeId', {
  state: () => {
    return {
      // 所有这些属性都将自动推断出它们的类型
      count: 0,
      name: 'Eduardo',
      isAdmin: true,
      items: [],
      hasChanged: true,
    }
  },
})
  • 使用示例
// 访问
const store = useStore()

// 单体修改
store.count++
// 群体修改
store.$patch({
  count: store.count + 1,
  age: 120,
  name: 'DIO',
})

// 订阅state
store.$subscribe((mutation, state)=>{
  localStorage.setItem('cart', JSON.stringify(state))
})
// 如果你想在组件卸载后依旧保留它们,请将 { detached: true } 作为第二个参数
store.$subscribe(callback, { detached: true })

watch(
  pinia.state,
  (state) => {
    // 每当状态发生变化时,将整个 state 持久化到本地存储。
    localStorage.setItem('piniaState', JSON.stringify(state))
  },
  { deep: true }
)

getter

Getter 完全等同于 store 的 state 的计算值。可以通过 defineStore() 中的 getters 属性来定义它们

import { useOtherStore } from './other-store'
export const useStore = defineStore('main', {
  state: () => ({
    count: 0,
  }),
  getters: {
    doubleCount: (state) => state.count * 2,
    doublePlusOne(): number {
      return this.doubleCount + 1 //通过this访问其他的getters
    },
    otherGetter(state) {
      const otherStore = useOtherStore() //也可以访问其他的Store
      return state.count + otherStore.data
    },
  },
})

Action

Action 相当于组件中的 method。它们可以通过 defineStore() 中的 actions 属性来定义

export const useCounterStore = defineStore('main', {
  state: () => ({
    count: 0,
  }),
  actions: { //类似 getter,action 也可通过 this 访问整个 store 实例;不同的是,action 可以是异步的
    increment() {
      this.count++
    },
    randomizeCounter() {
      this.count = Math.round(100 * Math.random())
    },
  },
})

插件

插件是通过 pinia.use() 添加到 pinia 实例的

import { createPinia } from 'pinia'

// 创建的每个 store 中都会添加一个名为 `secret` 的属性。
// 在安装此插件后,插件可以保存在不同的文件中
function SecretPiniaPlugin() {
  return { secret: 'the cake is a lie' }
}

const pinia = createPinia()
// 将该插件交给 Pinia
pinia.use(SecretPiniaPlugin)

// 在另一个文件中
const store = useStore()
store.secret // 'the cake is a lie'