Pinia状态管理有哪些常用API?

Pinia 是 Vue.js 的官方状态管理库,它取代了 Vuex,提供了更简洁、直观且类型友好的 API。以下是 Pinia 中最常用的核心 API 及其用法:


1. defineStore() - 定义 Store

这是创建一个 store 的核心 API。它接受一个唯一的 ID 和一个配置对象(或 setup 函数)。

javascript 复制代码
javascript
深色版本
// stores/counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  // 状态 (State)
  state: () => ({
    count: 0,
    name: 'Eduardo'
  }),

  // 计算属性 (Getters)
  getters: {
    doubleCount: (state) => state.count * 2,
    // 带参数的 getter
    getByName: (state) => {
      return (name) => state.name === name
    }
  },

  // 动作 (Actions)
  actions: {
    increment() {
      this.count++
    },
    decrement() {
      this.count--
    },
    // 异步操作
    async fetchUser() {
      const res = await fetch('/api/user')
      this.name = await res.json()
    }
  }
})

说明defineStore 返回一个函数(如 useCounterStore),调用它即可获取 store 实例。


2. state - 状态

用于定义 store 中的响应式数据。

  • 必须是一个函数,返回一个包含状态的对象。
  • 可以在组件中直接读取和修改。
yaml 复制代码
javascript
深色版本
state: () => ({
  count: 0,
  todos: []
})

3. getters - 计算属性

类似于 Vue 组件中的 computed,用于派生状态。

  • 接收 state 作为第一个参数。
  • 支持缓存,只有依赖的 state 变化时才会重新计算。
  • 可以接受参数(返回一个函数)。
javascript 复制代码
javascript
深色版本
getters: {
  // 基础 getter
  doubleCount: (state) => state.count * 2,

  // 带参数的 getter
  getTodoById: (state) => {
    return (id) => state.todos.find(todo => todo.id === id)
  }
}

4. actions - 动作

用于定义修改 state 的方法,支持同步和异步操作。

  • 可以通过 this 访问 stategetters 和其他 actions
  • 是修改 state 的唯一推荐方式(虽然可以直接修改,但不推荐)。
javascript 复制代码
javascript
深色版本
actions: {
  increment() {
    this.count++
  },
  async fetchData() {
    const data = await api.getData()
    this.todos = data
  }
}

5. 在组件中使用 Store

在组件中通过调用 useXxxStore() 函数来使用 store。

xml 复制代码
vue
深色版本
<script setup>
import { useCounterStore } from '@/stores/counter'

const counter = useCounterStore()

// 直接访问 state, getters, actions
console.log(counter.count)         // state
console.log(counter.doubleCount)   // getter
counter.increment()                // action
</script>

<template>
  <div>
    <p>Count: {{ counter.count }}</p>
    <p>Double: {{ counter.doubleCount }}</p>
    <button @click="counter.increment">+</button>
  </div>
</template>

注意 :从 store 中解构变量会失去响应性 。如果需要解构,应使用 storeToRefs()


6. storeToRefs() - 保持解构后的响应性

当你想从 store 中解构 state 或 getters 并保持响应性时,使用此工具函数。

xml 复制代码
vue
深色版本
<script setup>
import { storeToRefs } from 'pinia'
import { useCounterStore } from '@/stores/counter'

const counter = useCounterStore()
// ❌ 错误:count 失去响应性
// const { count, doubleCount } = counter

// ✅ 正确:使用 storeToRefs
const { count, doubleCount } = storeToRefs(counter)
const { increment } = counter // actions 不需要,因为不是响应式引用
</script>

7. mapState, mapGetters, mapActions - 映射辅助函数

在选项式 API(Options API)中,可以使用这些辅助函数将 store 的内容映射到组件中。

javascript 复制代码
javascript
深色版本
import { mapState, mapActions } from 'pinia'
import { useCounterStore } from '@/stores/counter'

export default {
  computed: {
    // 映射 state
    ...mapState(useCounterStore, ['count', 'name']),
    // 或者重命名
    ...mapState(useCounterStore, {
      myCount: 'count'
    })
  },
  methods: {
    // 映射 actions
    ...mapActions(useCounterStore, ['increment', 'fetchUser'])
  }
}

8. $reset() - 重置状态

每个 store 实例都暴露一个 $reset() 方法,用于将 state 重置为初始值。

scss 复制代码
javascript
深色版本
const counter = useCounterStore()
counter.$reset() // 将 count 重置为 0

9. $subscribe() - 订阅状态变化

监听 store 的 state 变化,类似于 Vuex 的 subscribe。

javascript 复制代码
javascript
深色版本
const counter = useCounterStore()

// 订阅 state 变化
const unsubscribe = counter.$subscribe((mutation, state) => {
  // mutation: 包含 type 等信息
  // state: 最新的 state
  console.log('State changed:', state.count)
})

// 取消订阅
// unsubscribe()

总结

API 用途
defineStore() 定义一个 store
state 定义响应式数据
getters 定义计算属性
actions 定义修改 state 的方法(支持异步)
useXxxStore() 在组件中使用 store
storeToRefs() 解构 store 时保持响应性
mapState / mapGetters / mapActions 选项式 API 中的映射辅助函数
$reset() 重置 state 到初始值
$subscribe() 监听 state 变化
相关推荐
宋浮檀s几秒前
应急响应——Web高危漏洞应急(SQL注入+XSS跨站+文件上传)
前端·网络·安全·web安全·xss
前端后腿哥几秒前
UNIAPPX UTS插件Widget开发完整教程(Android版)
前端·uni-app
大家的林语冰3 分钟前
AI 遥控代码截图,录制终端动画,定制自动化批量制图流程,解放你的双手~
前端·ai编程·trae
无聊的老谢9 分钟前
Vue 3 + Leaflet 实现高性能 Web GIS 基站监控平台
前端·javascript·vue.js
之歆11 分钟前
Day23_Bootstrap 前端框架完全指南:从栅格系统到组件化开发
开发语言·前端·javascript·前端框架·bootstrap·ecmascript·less
前端 贾公子11 分钟前
3.响应式系统基础:从发布订阅模式的角度理解 Vue2 的数据响应式原理(上)
前端·javascript·vue.js
2501_9400417414 分钟前
纯前端高阶实战:涵盖3D、音频可视化与复杂交互的开发命题
前端
AIFQuant15 分钟前
外汇交易平台技术栈深度解析:行情 API、清算、风控、前端一体化方案
前端·python·websocket·金融·restful
NiceCloud喜云8 小时前
Opus 4.8 的 Effort Control 怎么选:Low 到 Max 五档策略
android·java·大数据·前端·c++·python·spring
wordbaby9 小时前
React Native + RNOH:跨页面数据回传的最佳实践与避坑指南
前端·react native