粉粉蕉的笔记本粉粉蕉的笔记本
  • JAVA

    • 代码笔记
    • Java8实战
    • 分布式事务实战(Seata)
    • 模板引擎(FreeMarker)
    • SpringSecurity
    • Maven
  • PYTHON

    • 概述
    • python3
    • python3(菜鸟教程)
    • pandas
    • numpy
    • matplotlib
  • 中间件

    • Kafka
    • RocketMQ
    • Redis
    • MongoDB
    • Elastic Search
  • 数据库

    • Mysql
  • 前端

    • HTML
    • CSS
    • Vue学习笔记
  • 设计模式
  • 大数据

    • 概览
    • Hadoop
    • Hive
  • 机器学习

    • 机器学习概览
  • openclaw实战笔记
  • claudecode实战笔记
  • linux命令速查
  • windows命令速查
  • Docker笔记
  • kubernetes学习笔记
  • kubernetes实操笔记
  • 运维工具大全
  • git操作宝典
  • 概率论
  • 线性代数
  • 统计学
  • 金融知识学习
  • 聚宽
  • 因子分析
  • 后端

    • JAVA基础
    • JAVA多线程
    • JVM
    • 分布式相关
    • 数据库
  • 前端

    • HTML
    • CSS
    • JAVASCRIPT
    • VUE3
    • 网络
    • 前端工程化
    • nodejs
  • 健身

    • 笔记
    • 训练计划
  • 读书笔记

    • 《深度学习》
  • 其他

    • RSS
    • 资源导航
    • 医保
    • 装修攻略
我也想搭建这样的博客!
🚋开往
  • JAVA

    • 代码笔记
    • Java8实战
    • 分布式事务实战(Seata)
    • 模板引擎(FreeMarker)
    • SpringSecurity
    • Maven
  • PYTHON

    • 概述
    • python3
    • python3(菜鸟教程)
    • pandas
    • numpy
    • matplotlib
  • 中间件

    • Kafka
    • RocketMQ
    • Redis
    • MongoDB
    • Elastic Search
  • 数据库

    • Mysql
  • 前端

    • HTML
    • CSS
    • Vue学习笔记
  • 设计模式
  • 大数据

    • 概览
    • Hadoop
    • Hive
  • 机器学习

    • 机器学习概览
  • openclaw实战笔记
  • claudecode实战笔记
  • linux命令速查
  • windows命令速查
  • Docker笔记
  • kubernetes学习笔记
  • kubernetes实操笔记
  • 运维工具大全
  • git操作宝典
  • 概率论
  • 线性代数
  • 统计学
  • 金融知识学习
  • 聚宽
  • 因子分析
  • 后端

    • JAVA基础
    • JAVA多线程
    • JVM
    • 分布式相关
    • 数据库
  • 前端

    • HTML
    • CSS
    • JAVASCRIPT
    • VUE3
    • 网络
    • 前端工程化
    • nodejs
  • 健身

    • 笔记
    • 训练计划
  • 读书笔记

    • 《深度学习》
  • 其他

    • RSS
    • 资源导航
    • 医保
    • 装修攻略
我也想搭建这样的博客!
🚋开往
    • VUE3
    • VueRouter
    • Pinia
    • Vite

Pinia 使用教程

Pinia 是 Vue 3 官方推荐的状态管理库,是 Vuex 的替代方案。相比 Vuex,Pinia 更轻量、API 更简洁,并完整支持 TypeScript。

安装

npm install pinia

初始化

在 main.js 中注册 Pinia:

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'

const app = createApp(App)
const pinia = createPinia()

app.use(pinia)
app.mount('#app')

定义 Store

推荐在 src/stores/ 目录下创建 Store 文件。

Option Store 写法

类似 Vue 2 的 Options API 风格:

// src/stores/counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0,
    name: 'Eduardo',
  }),
  getters: {
    doubleCount: (state) => state.count * 2,
  },
  actions: {
    increment() {
      this.count++
    },
    async fetchUser(userId) {
      const res = await fetch(`/api/user/${userId}`)
      this.name = (await res.json()).name
    },
  },
})

Setup Store 写法(推荐)

类似 Vue 3 的 Composition API 风格,更灵活:

// src/stores/counter.js
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

export const useCounterStore = defineStore('counter', () => {
  // state
  const count = ref(0)
  const name = ref('Eduardo')

  // getters
  const doubleCount = computed(() => count.value * 2)

  // actions
  function increment() {
    count.value++
  }

  async function fetchUser(userId) {
    const res = await fetch(`/api/user/${userId}`)
    name.value = (await res.json()).name
  }

  return { count, name, doubleCount, increment, fetchUser }
})

在组件中使用 Store

<script setup>
import { useCounterStore } from '@/stores/counter'

const counter = useCounterStore()
</script>

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

解构 Store(保持响应式)

直接解构会丢失响应式,需使用 storeToRefs:

<script setup>
import { storeToRefs } from 'pinia'
import { useCounterStore } from '@/stores/counter'

const counter = useCounterStore()

// 用 storeToRefs 解构 state 和 getters(保持响应式)
const { count, name, doubleCount } = storeToRefs(counter)

// actions 可以直接解构,无需 storeToRefs
const { increment } = counter
</script>

修改 State

方式一:直接修改

const counter = useCounterStore()
counter.count++
counter.name = 'Tom'

方式二:$patch(批量修改,性能更好)

// 对象写法
counter.$patch({
  count: 10,
  name: 'Tom',
})

// 函数写法(适合复杂修改)
counter.$patch((state) => {
  state.count++
  state.name = 'Tom'
})

方式三:通过 Actions 修改(推荐)

counter.increment()

重置 State

Option Store 可直接调用 $reset():

counter.$reset()

Setup Store 需手动实现:

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)

  function $reset() {
    count.value = 0
  }

  return { count, $reset }
})

监听 State 变化

$subscribe

counter.$subscribe((mutation, state) => {
  console.log('mutation type:', mutation.type)
  console.log('new state:', state)
  // 可持久化存储
  localStorage.setItem('counter', JSON.stringify(state))
})

watch

import { watch } from 'vue'

watch(
  () => counter.count,
  (newVal, oldVal) => {
    console.log(`count changed: ${oldVal} -> ${newVal}`)
  }
)

监听 Actions

counter.$onAction(({ name, args, after, onError }) => {
  console.log(`action "${name}" called with args:`, args)

  after((result) => {
    console.log(`action "${name}" finished`)
  })

  onError((error) => {
    console.error(`action "${name}" failed:`, error)
  })
})

持久化插件(pinia-plugin-persistedstate)

npm install pinia-plugin-persistedstate
// main.js
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)

在 Store 中开启持久化:

export const useCounterStore = defineStore('counter', {
  state: () => ({ count: 0 }),
  persist: true, // 默认存储到 localStorage
})

// 自定义配置
export const useUserStore = defineStore('user', {
  state: () => ({ token: '', userInfo: {} }),
  persist: {
    key: 'user-store',         // 存储键名
    storage: sessionStorage,   // 使用 sessionStorage
    paths: ['token'],          // 只持久化 token 字段
  },
})

在 Store 外使用

在非组件环境(如路由守卫、请求拦截器)中使用 Store,需传入 pinia 实例:

// router/index.js
import { useUserStore } from '@/stores/user'

router.beforeEach((to) => {
  // 确保 pinia 已初始化后再调用
  const userStore = useUserStore()
  if (to.meta.requiresAuth && !userStore.token) {
    return '/login'
  }
})

与 Vuex 对比

特性PiniaVuex 4
TypeScript 支持完整支持有限支持
Mutations无(直接修改)需要定义
模块化天然支持(每个 Store 独立)需要 modules 配置
DevTools支持支持
代码量少多
Vue 版本Vue 2 / Vue 3Vue 2 / Vue 3
Last Updated: 6/24/26, 7:20 AM
Contributors: dongyz8
Prev
VueRouter
Next
Vite