Pinia 状态管理集成教程(Vue 3 项目实战)

4 阅读3分钟

📚 Pinia 状态管理集成教程(Vue 3 项目实战)

本教程将手把手教你为 Vue 3 项目集成 Pinia,实现全局状态管理,适用于个人信息、地址管理等模块。


🎯 学习目标

  • 安装并配置 Pinia
  • 创建 Store 管理用户数据
  • 在组件中使用 Store
  • 实现编辑/保存的隔离状态

⚙️ 第 1 步:安装 Pinia

npm install pinia

💡 验证安装
package.json 中应出现 "pinia": "^2.x.x"


🏗️ 第 2 步:创建 Store

1. 创建目录结构

src/
└── stores/
    └── user.js    # 用户数据 Store

2. 编写 src/stores/user.js

import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
  // 状态(相当于 Vuex 的 state)
  state: () => ({
    // 用户信息
    userData: {
      nickname: 'Vue Learner',
      telno: '138****1234'
    },
    isEditing: false, // 个人信息编辑状态

    // 地址列表
    addresses: [
      { id: 1, name: '张三', phone: '138****1234', address: '北京市朝阳区' }
    ],
    editingAddress: null // null=新增地址, {id,...}=编辑地址
  }),

  // 方法(相当于 Vuex 的 mutations + actions)
  actions: {
    // 更新用户字段
    updateField(field, value) {
      this.userData[field] = value
    },
    
    // 切换个人信息编辑状态
    setEditing(editing) {
      this.isEditing = editing
    },

    // 地址管理
    addAddress(data) {
      this.addresses.push({ ...data, id: Date.now() })
    },
    updateAddress(id, data) {
      const addr = this.addresses.find(a => a.id === id)
      if (addr) Object.assign(addr, data)
    },
    deleteAddress(id) {
      this.addresses = this.addresses.filter(a => a.id !== id)
    },
    setEditingAddress(addr) {
      this.editingAddress = addr
    }
  }
})

🔑 关键点

  • state 必须是函数(返回初始状态对象)
  • actions 可直接修改 this(无需 return 新状态)

🔌 第 3 步:在项目中注册 Pinia

修改 src/main.js

import { createApp } from 'vue'
import { createPinia } from 'pinia' // 1. 引入 createPinia
import App from './App.vue'
import './assets/main.css'

const app = createApp(App)
const pinia = createPinia() // 2. 创建 Pinia 实例

app.use(pinia) // 3. 注册 Pinia
app.mount('#app')

⚠️ 必须先 app.use(pinia)app.mount(),否则组件中调用 useStore() 会报错!


🧩 第 4 步:在组件中使用 Store

1. 导入 Store

<script setup>
import { useUserStore } from '@/stores/user'

const userStore = useUserStore() // 获取 store 实例
</script>

2. 读取状态

<template>
  <!-- 直接访问 store 数据 -->
  <p>昵称:{{ userStore.userData.nickname }}</p>
</template>

3. 调用方法

// 更新数据
userStore.updateField('nickname', '新昵称')

// 切换状态
userStore.setEditing(true)

🛡️ 第 5 步:实现编辑隔离(关键技巧)

问题场景

编辑表单时,不能直接修改 store 数据(否则取消编辑会保留错误输入)

解决方案:本地草稿区 + 保存时提交

<script setup>
import { ref } from 'vue'
import { useUserStore } from '@/stores/user'

const userStore = useUserStore()

// 1. 从 store 复制初始值(创建草稿)
const nickname = ref(userStore.userData.nickname)
const telno = ref(userStore.userData.telno)

// 2. 保存时提交到 store
const onSave = () => {
  // 验证通过后更新 store
  userStore.updateField('nickname', nickname.value)
  userStore.updateField('telno', telno.value)
  userStore.setEditing(false) // 关闭编辑
}

// 3. 取消时丢弃草稿
const onCancel = () => {
  userStore.setEditing(false)
}
</script>

<template>
  <!-- 绑定本地 ref(非 store) -->
  <input v-model="nickname" />
  <input v-model="telno" />
  
  <button @click="onSave">保存</button>
  <button @click="onCancel">取消</button>
</template>

优势

  • 编辑过程不污染全局状态
  • 取消操作零成本(直接丢弃本地变量)

🧪 验证清单

  • 安装 Pinia 无报错
  • main.js 中先 use(pinia)mount()
  • 组件中能读取 userStore.userData
  • 编辑表单使用本地 ref 作为草稿区
  • 保存时才更新 store,取消时不更新

💡 最佳实践

场景推荐做法
简单状态直接读写 userStore.xxx
表单编辑ref/reactive 作草稿区
复杂逻辑actions 中封装业务逻辑
多模块拆分为 userStore/cartStore

🚀 下一步

完成本教程后,你的项目将具备:

  • 全局状态管理能力
  • 安全的表单编辑流程
  • 可扩展的 Store 结构

需要 地址管理模块的 Pinia 实现细节数据持久化方案 吗? 😊