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 变化
相关推荐
gAlAxy...17 分钟前
IntelliJ IDEA 四种项目构建:从普通 Java 到 Maven Web 项目
前端·firefox
my一阁19 分钟前
2025-web集群-问题总结
前端·arm开发·数据库·nginx·负载均衡·web
会飞的小妖20 分钟前
个人博客系统(十一、前端-简短的配置)
前端
念念不忘 必有回响2 小时前
nginx前端部署与Vite环境变量配置指南
前端·nginx·vite
JIngJaneIL2 小时前
篮球论坛|基于SprinBoot+vue的篮球论坛系统(源码+数据库+文档)
java·前端·数据库·vue.js·论文·毕设·篮球论坛系统
程序猿阿伟4 小时前
《首屏加载优化手册:Vue3+Element Plus项目提速的技术细节》
前端·javascript·vue.js
fruge5 小时前
Vue Pinia 状态管理实战指南
前端·vue.js·ubuntu
sean6 小时前
开发一个自己的 claude code
前端·后端·ai编程
用户21411832636026 小时前
dify案例分享-用 Dify 一键生成教学动画 HTML!AI 助力,3 分钟搞定专业级课件
前端
太过平凡的小蚂蚁8 小时前
Kotlin 协程中常见的异步返回与控制方式(速览)
开发语言·前端·kotlin