Pinia

Pinia 是 Vue 的状态管理库,允许在跨组件/页面之间共享状态,由 Vue 核心团队维护,对 Vue 2 和 Vue 3 都可用。类似于react中的mobx和redux。Vuex是 Vue 之前的官方状态管理库。由于 Pinia 在生态系统中能够承担相同的职责且能做得更好,因此 Vuex 现在处于维护模式。它仍然可以工作,但不再接受新的功能。对于新的应用,建议使用 Pinia。

https://pinia.vuejs.org/

安装与使用

安装

yarn add pinia
# 或者使用 npm
npm install pinia

使用

  1. 引入到main.ts

main.ts

import { createPinia } from 'pinia'

app.use(createPinia())
  1. 定义一个store

./src/stores/counterStore.ts

import { defineStore } from 'pinia',

const useCounterStore = defineStore('counterStore', {
  state: () => ({
    counter: 0
  })
})
  1. 访问store
<template>
  <div>
    {{ counterStore.counter }}
  </div>
</template>

<script setup lang="ts">
import useCounterStore from '../stores/counterStore'
const counterStore = useCounterStore()
</script>

核心概念: state、getters、actions

state

state 是 store 的核心部分。 在 Pinia 中,状态被定义为返回初始状态的函数。

import { defineStore } from 'pinia'

const useStore = defineStore('storeId', {
  // 推荐使用 完整类型推断的箭头函数
  state: () => {
    return {
      // 所有这些属性都将自动推断其类型
      counter: 0,
      name: 'Eduardo',
      isAdmin: true,
    }
  },
})
访问 state

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

const store = useStore()

store.counter++
重置状态

您可以通过调用 store 上的 $reset() 方法将状态 重置 到其初始值:

const store = useStore()

store.$reset()

tip : 可以在 pinia 实例上查看整个状态:

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

更多用法查看官网: https://pinia.vuejs.org/core-concepts/state.html

getter

Getter 完全等同于 Store 状态的计算值。 它们可以用 defineStore() 中的 getters 属性定义。 他们接收“状态”作为第一个参数:

export const useStore = defineStore('main', {
  state: () => ({
    counter: 0,
  }),
  getters: {
    doubleCount: (state) => state.counter * 2,
  },
})

然后可以在store 实例上访问 getter:

<template>
  <p>Double count is {{ store.doubleCount }}</p>
</template>

<script lang="ts" setup>
import useStore from '../stores/counterStore'
const store = useStore()
</script>

更多用法查看官网:https://pinia.vuejs.org/core-concepts/getters.html

actions

Actions 相当于组件中的methods。它们可以使用 defineStore() 中的 actions 属性定义,并且它们非常适合定义业务逻辑

export const useStore = defineStore('main', {
  state: () => ({
    counter: 0,
  }),
  actions: {
    increment() {
      this.counter++
    },
    randomizeCounter() {
      this.counter = Math.round(100 * Math.random())
    },
  },
})

actions 可以是异步的,您可以在其中await 任何 API 调用甚至其他操作。

import { mande } from 'mande'

const api = mande('/api/users')

export const useUsers = defineStore('users', {
  state: () => ({
    userData: null,
    // ...
  }),

  actions: {
    async registerUser(login, password) {
      try {
        this.userData = await api.post({ login, password })
        showTooltip(`Welcome back ${this.userData.name}!`)
      } catch (error) {
        showTooltip(error)
        return error
      }
    },
  },
})

更多用法查看官网:https://pinia.vuejs.org/core-concepts/actions.html

Q.E.D.


永远自由,永远热爱