小白学Pinia状态管理

目录

[1. 什么是 Pinia?](#1. 什么是 Pinia?)

[2. 为什么需要 Pinia?](#2. 为什么需要 Pinia?)

[3. Pinia 的三个核心概念](#3. Pinia 的三个核心概念)

[State(状态)- 存储数据](#State(状态)- 存储数据)

[Getters(计算属性)- 处理数据](#Getters(计算属性)- 处理数据)

[Actions(方法)- 修改数据](#Actions(方法)- 修改数据)

[4. 创建一个简单的 Store](#4. 创建一个简单的 Store)

[5. 在组件中使用 Store](#5. 在组件中使用 Store)

[6. 再来一个示例](#6. 再来一个示例)

[7. 在组件中的使用示例](#7. 在组件中的使用示例)

[8. Pinia 的优势](#8. Pinia 的优势)

[9. 常见使用场景](#9. 常见使用场景)

[10. 学习建议](#10. 学习建议)


1. 什么是 Pinia?

Pinia 就像一个全局的数据仓库 ,让不同的 Vue 组件能够共享数据

比喻:想象一个图书馆(Pinia),所有人(Vue组件)都可以去借书(读取数据)、还书(修改数据)。

2. 为什么需要 Pinia?

问题场景

javascript 复制代码
// 组件A需要用户信息
const userInfo = { name: '张三', age: 25 }

// 组件B也需要这个用户信息
// 组件C也需要这个用户信息
// 怎么在这些组件之间共享数据?

解决方案:用 Pinia 存储全局数据,所有组件都能访问。

3. Pinia 的三个核心概念

State(状态)- 存储数据

javascript 复制代码
state: () => ({
  currentType: 'type1',  // 当前机器类型
  userInfo: null,        // 用户信息
  count: 0              // 计数器
})

理解 :State 就是存放数据的地方,类似于组件的 data。

Getters(计算属性)- 处理数据

javascript 复制代码
getters: {
  // 根据当前类型获取配置
  currentConfig: (state) => {
    return state.machineConfig[state.currentType]
  },
  
  // 判断是否是成年人
  isAdult: (state) => {
    return state.userInfo?.age >= 18
  }
}

理解:Getters 就像计算属性,基于 state 计算出新的值。

Actions(方法)- 修改数据

javascript 复制代码
actions: {
  // 设置机器类型
  setMachineType(type) {
    this.currentType = type
  },
  
  // 设置用户信息
  setUserInfo(info) {
    this.userInfo = info
  }
}

理解 :Actions 就是修改 state 的方法,类似于组件的 methods。

4. 创建一个简单的 Store

让我们创建一个用户信息的 Store:

javascript 复制代码
// store/user.js
import { defineStore } from 'pinia'

export const useUserStore = defineStore('user', {
  // 1. State - 存储数据
  state: () => ({
    name: '',
    age: 0,
    isLogin: false
  }),

  // 2. Getters - 计算属性
  getters: {
    // 获取用户显示名称
    displayName: (state) => {
      return state.name || '游客'
    },
    
    // 判断是否成年
    isAdult: (state) => {
      return state.age >= 18
    }
  },

  // 3. Actions - 修改数据的方法
  actions: {
    // 登录
    login(name, age) {
      this.name = name
      this.age = age
      this.isLogin = true
    },
    
    // 登出
    logout() {
      this.name = ''
      this.age = 0
      this.isLogin = false
    }
  }
})

5. 在组件中使用 Store

javascript 复制代码
<!-- UserProfile.vue -->
<template>
  <div>
    <h1>用户信息</h1>
    <p>姓名:{{ userStore.displayName }}</p>
    <p>年龄:{{ userStore.age }}</p>
    <p>状态:{{ userStore.isLogin ? '已登录' : '未登录' }}</p>
    <p>{{ userStore.isAdult ? '成年人' : '未成年人' }}</p>
    
    <button @click="handleLogin">登录</button>
    <button @click="handleLogout">登出</button>
  </div>
</template>

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

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

// 登录方法
const handleLogin = () => {
  userStore.login('张三', 25)
}

// 登出方法
const handleLogout = () => {
  userStore.logout()
}
</script>

6. 再来一个示例

创建一个机型配置 Store:

javascript 复制代码
export const useMachineStore = defineStore('machine', {
  // 存储机器相关数据
  state: () => ({
    currentType: 'type1',  // 当前机器类型
    machineConfig: {       // 机器配置信息
      type1: { name: '无打印', features: ['query', 'payment'] },
      type2: { name: '报告打印', features: ['query', 'payment', 'reportPrint'] },
      type3: { name: '发票打印', features: ['query', 'payment', 'invoicePrint'] }
    }
  }),

  // 基于数据计算新值
  getters: {
    // 获取当前机器配置
    currentConfig: (state) => {
      return state.machineConfig[state.currentType]
    },
    
    // 检查是否支持某功能
    hasFeature: (state) => {
      return (feature) => {
        const config = state.machineConfig[state.currentType]
        return config.features.includes(feature)
      }
    }
  },

  // 修改数据的方法
  actions: {
    // 切换机器类型
    setMachineType(type) {
      this.currentType = type
    }
  }
})

7. 在组件中的使用示例

javascript 复制代码
<!-- MachineInfo.vue -->
<template>
  <div>
    <h2>{{ machineStore.currentConfig.name }}</h2>
    <p>支持的功能:</p>
    <ul>
      <li v-if="machineStore.hasFeature('query')">查询功能</li>
      <li v-if="machineStore.hasFeature('payment')">缴费功能</li>
      <li v-if="machineStore.hasFeature('reportPrint')">报告打印</li>
    </ul>
    
    <button @click="switchMachine">切换机器类型</button>
  </div>
</template>

<script setup>
import { useMachineStore } from '@/store/machine'

const machineStore = useMachineStore()

const switchMachine = () => {
  // 切换到下一个类型
  const types = ['type1', 'type2', 'type3']
  const currentIndex = types.indexOf(machineStore.currentType)
  const nextIndex = (currentIndex + 1) % types.length
  machineStore.setMachineType(types[nextIndex])
}
</script>

8. Pinia 的优势

  1. 简单易用:语法简洁,容易理解。
  2. 类型安全:支持 TypeScript。
  3. 开发工具:有专门的调试工具。
  4. 模块化:每个功能可以创建独立的 store。

9. 常见使用场景

  • 用户信息管理:登录状态、用户资料。
  • 主题设置:暗色模式、语言设置。
  • 购物车:商品列表、总价计算。
  • 全局配置:API 地址、系统设置。

10. 学习建议

  1. 从简单开始:先创建一个计数器 store。
  2. 理解概念state存数据,getters算数据,actions改数据
  3. 多练习:在实际项目中使用。
  4. 看文档:官方文档很详细。
相关推荐
奋飛4 分钟前
TypeScript系列:第六篇 - 编写高质量的TS类型
javascript·typescript·ts·declare·.d.ts
老A技术联盟4 分钟前
从小白入门,基于Cursor开发一个前端小程序之Cursor 编程实践与案例分析
前端·小程序
风铃喵游8 分钟前
构建引擎: 打造小程序编译器
前端·小程序·架构
sunbyte13 分钟前
50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | ThemeClock(主题时钟)
前端·javascript·css·vue.js·前端框架·tailwindcss
小飞悟21 分钟前
🎯 什么是模块化?CommonJS 和 ES6 Modules 到底有什么区别?小白也能看懂
前端·javascript·设计
浏览器API调用工程师_Taylor22 分钟前
AOP魔法:一招实现登录弹窗的全局拦截与动态处理
前端·javascript·vue.js
FogLetter23 分钟前
初识图片懒加载:让网页像"懒人"一样聪明加载
前端·javascript
微客鸟窝24 分钟前
一文搞懂NVM管理Node.js:从安装到实战全攻略
前端
归于尽25 分钟前
Cookie、Session、JWT 的前世今生
前端
程序员辉哥26 分钟前
学会在Cursor中使用Rules生成代码后可以躺平了吗?
前端·后端