DukeDuke
主页
项目文档
技术文档
  • 单机版
  • 微服务
  • 代办项目
  • 优鲜项目
项目管理
关于我们
主页
项目文档
技术文档
  • 单机版
  • 微服务
  • 代办项目
  • 优鲜项目
项目管理
关于我们
  • 技术文档

    • 网络原理

      • 交换机
      • 路由器
      • TCP/IP协议
      • HTTP 与 HTTPS
    • 软件架构

      • 什么是软件架构
      • 分层架构
      • 微服务架构
      • 事件驱动架构
      • 领域驱动设计(DDD)
      • 架构图
      • 高并发系统
    • Vue3

      • Vue3简介
      • Vue3响应式系统
      • Vue3组合式API
      • Vue3生命周期
      • Vue3模板语法
      • Vue3组件系统
      • Vue3 路由系统
      • Vue3 状态管理
      • Vue3 性能优化
      • Vue3 TypeScript 支持
      • Vue3 项目实战
      • VUE 面试题大全
      • Node.js 安装
    • JAVA

      • JVM

        • 认识JVM
        • JVM类加载器
        • 运行时数据区
        • 执行引擎
        • 本地方法接口
        • 本地方法库
        • JVM垃圾回收
        • JVM性能监控
        • JVM调优
      • 设计模式
        • 单例模式
        • 工厂模式
        • 策略模式
        • 适配器模式
        • 建造者模式
        • 原型模式
        • 装饰器模式
        • 代理模式
        • 外观模式
        • 享元模式
        • 组合模式
        • 桥接模式
      • Java多线程

        • Java 线程基础详解
        • Java 线程池详解
        • Java ThreadLocal 详解
        • Java volatile 详解
        • Java 线程间通信详解
        • Java 线程安全详解
        • Java 线程调度详解
        • Java 线程优先级详解

        • Java 线程中断详解
        • Java 线程死锁详解
      • Java反射
      • Java 面试题

        • Java 基础概念面试题
        • Java 面向对象编程面试题
        • Java 集合框架面试题
        • Java 多线程与并发面试题
        • JVM 与内存管理面试题
        • Java I/O 与 NIO 面试题
        • Java 异常处理面试题
        • Java 反射与注解面试题
        • Java Spring 框架面试题
        • Java 数据库与 JDBC 面试题
        • Java 性能优化面试题
        • Java 实际项目经验面试题
        • Java 高级特性面试题
        • Java 面试准备建议
    • Python

      • Python简介
      • Python安装
      • Python hello world
      • Python基础语法
      • Python数据类型
      • Python数字
      • Python字符串
      • Python列表
      • Python元组
      • Python字典
      • Python日期时间
      • Python文件操作
      • Python异常处理
      • Python函数
      • Python类
      • Python模块
      • Python包
      • Python多线程
      • Python面向对象
      • Python爬虫
      • Django web框架
      • Python 面试题

        • Python 面试题导航
        • Python 基础概念
        • Python 面向对象编程
        • Python 数据结构
        • Python 高级特性
        • Python 框架
        • Python 性能优化
        • Python 项目经验
    • Spring

      • Spring
      • Springboot
      • Spring Security 安全框架
      • SpringBoot 中的事件详解
      • SpringBoot 中的定时任务详解
      • SpringBoot 自动装配原理与源码解释
    • Mybatis

      • Mybatis
      • Mybatis-Plus
    • 数据库

      • Redis

        • Redis简介
        • Redis(单机)安装
        • Redis配置
        • Redis数据结构
        • RDB、AOF 和混合持久化机制
        • Redis内存管理
        • Redis缓存一致性
        • Redis缓存穿透
        • Redis缓存击穿
        • Redis缓存雪崩
        • Redis Lua脚本
        • Redis主从复制
        • Redis哨兵模式
        • Redis集群
        • Redis数据分片
        • Redis CPU使用率过高
        • Redis面试题
      • MySQL

        • MySQL简介
        • MySQL安装
        • MySQL配置
        • MYSQL日常维护
        • MYSQL优化-慢查询
        • MYSQL优化-索引
        • MYSQL数据库设计规范
    • 消息队列

      • RocketMQ
      • Kafka
      • RabbitMQ
      • 消息队列面试题
    • 微服务

      • SpringCloud 微服务
      • Eureka 注册中心
      • Nacos 注册中心
      • Gateway 网关
      • Feign 服务调用
      • Sentinel 限流 与 熔断
      • Seata 分布式事务
      • CAP 理论
      • Redis 分布式锁
      • 高并发系统设计
    • ELK日志分析系统

      • Elasticsearch 搜索引擎
      • Logstash 数据处理
      • Kibana 可视化
      • ELK 实战
    • 开放API

      • 开放API设计
      • 开放API示例项目
    • 人工智能

      • 人工智能简介
      • 机器学习

      • 深度学习

      • 自然语言处理

      • 计算机视觉

        • CUDA与cuDNN详细安装
        • Conda 安装
        • Pytorch 深度学习框架
        • yolo 目标检测
        • TensorRT 深度学习推理优化引擎
        • TensorFlow 机器学习
        • CVAT 图像标注
        • Windows 下安装 CUDA、cuDNN、TensorRT、TensorRT-YOLO 环境
        • Windows10+CUDA+cuDNN+TensorRT+TensorRT-YOLO 部署高性能YOLO11推理
    • 大数据

      • 大数据简介
      • Hadoop 数据存储
      • Flume 数据采集
      • Sqoop 数据导入导出
      • Hive 数据仓库
      • Spark 数据处理
      • Flink 数据处理
      • Kafka 数据采集
      • HBase 数据存储
      • Elasticsearch 搜索引擎
    • 图像处理

      • 图像处理简介
      • 医学图像web呈现
      • 医学图像处理
      • 切片细胞分离问题
    • 服务器&运维

      • Linux 系统

        • Linux 系统管理
        • Linux 网络管理
        • Linux 文件管理
        • Linux 命令大全
      • Nginx Web 服务器

        • Nginx 安装 与 配置
        • Nginx 负载均衡
        • Nginx SSL证书配置
        • Nginx Keepalived 高可用
      • Docker 容器

        • Docker 简介
        • Docker 安装与配置
        • Docker 命令
        • Docker 部署 Nginx
        • Docker 部署 MySQL
        • Docker 部署 Redis
      • 服务器

        • 塔式服务器
        • 机架式服务器
        • 刀片服务器
      • Git 版本控制
      • Jenkins 持续集成
      • Jmeter 性能测试
      • Let's Encrypt 免费SSL证书
    • 简历

      • 项目经理简历
      • 开发工程师简历

Vue3 状态管理 (Pinia) 详解

概述

Pinia 是 Vue3 推荐的状态管理库,它比 Vuex 更轻量、更类型安全。状态管理就像是应用的"大脑",集中管理所有组件需要共享的数据。

状态管理架构

基本概念

1. Store

Store 是 Pinia 的核心概念,它是一个包含状态和业务逻辑的实体。

// stores/counter.js
import { defineStore } from "pinia";

export const useCounterStore = defineStore("counter", {
  // 状态
  state: () => ({
    count: 0,
    name: "计数器",
  }),

  // 计算属性
  getters: {
    doubleCount: (state) => state.count * 2,
    doubleCountPlusOne: (state) => state.count * 2 + 1,
  },

  // 方法
  actions: {
    increment() {
      this.count++;
    },
    decrement() {
      this.count--;
    },
    incrementBy(amount) {
      this.count += amount;
    },
  },
});

2. 在组件中使用 Store

<template>
  <div>
    <h2>{{ counter.name }}</h2>
    <p>当前计数: {{ counter.count }}</p>
    <p>双倍计数: {{ counter.doubleCount }}</p>
    <p>双倍计数加一: {{ counter.doubleCountPlusOne }}</p>

    <button @click="counter.increment">增加</button>
    <button @click="counter.decrement">减少</button>
    <button @click="counter.incrementBy(5)">增加5</button>
  </div>
</template>

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

export default {
  setup() {
    const counter = useCounterStore()

    return {
      counter
    }
  }
}
</script>

Store 结构详解

1. State

State 是 Store 的数据源,类似于组件的 data。

export const useUserStore = defineStore("user", {
  state: () => ({
    // 基本类型
    name: "",
    age: 0,
    isLoggedIn: false,

    // 对象类型
    profile: {
      avatar: "",
      email: "",
      phone: "",
    },

    // 数组类型
    permissions: [],

    // 复杂对象
    settings: {
      theme: "light",
      language: "zh-CN",
      notifications: {
        email: true,
        push: false,
        sms: true,
      },
    },
  }),
});

2. Getters

Getters 类似于计算属性,基于 state 派生数据。

export const useUserStore = defineStore("user", {
  state: () => ({
    users: [
      { id: 1, name: "张三", age: 25, role: "admin" },
      { id: 2, name: "李四", age: 30, role: "user" },
      { id: 3, name: "王五", age: 28, role: "user" },
    ],
  }),

  getters: {
    // 基本 getter
    totalUsers: (state) => state.users.length,

    // 带参数的 getter
    getUserById: (state) => (id) => {
      return state.users.find((user) => user.id === id);
    },

    // 使用其他 getter
    adminUsers: (state) => state.users.filter((user) => user.role === "admin"),
    adminCount: (state, getters) => getters.adminUsers.length,

    // 复杂计算
    userStats: (state) => {
      const total = state.users.length;
      const admins = state.users.filter((user) => user.role === "admin").length;
      const users = total - admins;
      const avgAge =
        state.users.reduce((sum, user) => sum + user.age, 0) / total;

      return {
        total,
        admins,
        users,
        avgAge: Math.round(avgAge),
      };
    },
  },
});

3. Actions

Actions 用于处理异步操作和业务逻辑。

export const useUserStore = defineStore("user", {
  state: () => ({
    users: [],
    loading: false,
    error: null,
  }),

  actions: {
    // 异步获取用户列表
    async fetchUsers() {
      this.loading = true;
      this.error = null;

      try {
        const response = await fetch("/api/users");
        const data = await response.json();
        this.users = data;
      } catch (error) {
        this.error = error.message;
      } finally {
        this.loading = false;
      }
    },

    // 添加用户
    async addUser(userData) {
      try {
        const response = await fetch("/api/users", {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify(userData),
        });

        const newUser = await response.json();
        this.users.push(newUser);

        return newUser;
      } catch (error) {
        this.error = error.message;
        throw error;
      }
    },

    // 更新用户
    async updateUser(id, updates) {
      try {
        const response = await fetch(`/api/users/${id}`, {
          method: "PUT",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify(updates),
        });

        const updatedUser = await response.json();
        const index = this.users.findIndex((user) => user.id === id);

        if (index !== -1) {
          this.users[index] = updatedUser;
        }

        return updatedUser;
      } catch (error) {
        this.error = error.message;
        throw error;
      }
    },

    // 删除用户
    async deleteUser(id) {
      try {
        await fetch(`/api/users/${id}`, {
          method: "DELETE",
        });

        const index = this.users.findIndex((user) => user.id === id);
        if (index !== -1) {
          this.users.splice(index, 1);
        }
      } catch (error) {
        this.error = error.message;
        throw error;
      }
    },

    // 重置状态
    resetState() {
      this.users = [];
      this.loading = false;
      this.error = null;
    },
  },
});

组合式 API 风格

Pinia 也支持组合式 API 的写法,使用 defineStore 的第二个参数为函数。

export const useCounterStore = defineStore("counter", () => {
  // 状态
  const count = ref(0);
  const name = ref("计数器");

  // 计算属性
  const doubleCount = computed(() => count.value * 2);
  const doubleCountPlusOne = computed(() => count.value * 2 + 1);

  // 方法
  function increment() {
    count.value++;
  }

  function decrement() {
    count.value--;
  }

  function incrementBy(amount) {
    count.value += amount;
  }

  return {
    count,
    name,
    doubleCount,
    doubleCountPlusOne,
    increment,
    decrement,
    incrementBy,
  };
});

Store 之间的交互

1. 在 Store 中使用其他 Store

export const useCartStore = defineStore("cart", {
  state: () => ({
    items: [],
  }),

  getters: {
    totalItems: (state) => state.items.length,
    totalPrice: (state) => {
      return state.items.reduce(
        (total, item) => total + item.price * item.quantity,
        0
      );
    },
  },

  actions: {
    addItem(product, quantity = 1) {
      // 使用用户 store 检查登录状态
      const userStore = useUserStore();

      if (!userStore.isLoggedIn) {
        throw new Error("请先登录");
      }

      const existingItem = this.items.find((item) => item.id === product.id);

      if (existingItem) {
        existingItem.quantity += quantity;
      } else {
        this.items.push({
          ...product,
          quantity,
        });
      }
    },
  },
});

2. 组合多个 Store

export const useAppStore = defineStore("app", () => {
  const userStore = useUserStore();
  const cartStore = useCartStore();
  const counterStore = useCounterStore();

  // 应用级别的状态
  const theme = ref("light");
  const language = ref("zh-CN");

  // 应用级别的计算属性
  const isReady = computed(() => {
    return userStore.isLoggedIn && !cartStore.loading;
  });

  // 应用级别的方法
  function resetAllStores() {
    userStore.resetState();
    cartStore.resetState();
    counterStore.resetState();
    theme.value = "light";
    language.value = "zh-CN";
  }

  return {
    theme,
    language,
    isReady,
    resetAllStores,
  };
});

持久化存储

1. 使用 pinia-plugin-persistedstate

// main.js
import { createPinia } from "pinia";
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";

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

app.use(pinia);
export const useUserStore = defineStore("user", {
  state: () => ({
    token: "",
    userInfo: null,
  }),

  persist: {
    // 启用持久化
    enabled: true,

    // 指定要持久化的字段
    paths: ["token", "userInfo"],

    // 存储策略
    strategies: [
      {
        key: "user",
        storage: localStorage,
        paths: ["token", "userInfo"],
      },
      {
        key: "user-session",
        storage: sessionStorage,
        paths: ["token"],
      },
    ],
  },
});

2. 手动实现持久化

export const useSettingsStore = defineStore("settings", {
  state: () => ({
    theme: "light",
    language: "zh-CN",
    fontSize: 14,
  }),

  actions: {
    // 保存到本地存储
    saveToStorage() {
      localStorage.setItem(
        "settings",
        JSON.stringify({
          theme: this.theme,
          language: this.language,
          fontSize: this.fontSize,
        })
      );
    },

    // 从本地存储加载
    loadFromStorage() {
      const saved = localStorage.getItem("settings");
      if (saved) {
        const settings = JSON.parse(saved);
        this.theme = settings.theme || "light";
        this.language = settings.language || "zh-CN";
        this.fontSize = settings.fontSize || 14;
      }
    },

    // 更新设置并保存
    updateSettings(updates) {
      Object.assign(this, updates);
      this.saveToStorage();
    },
  },
});

开发工具支持

Pinia 提供了优秀的开发工具支持,可以在 Vue DevTools 中查看和调试 Store。

// 在开发环境中启用
if (process.env.NODE_ENV === "development") {
  const { devtools } = await import("pinia/devtools");
  devtools();
}

最佳实践

1. Store 设计原则

  • 按功能模块划分 Store
  • 保持 Store 的单一职责
  • 避免 Store 之间的循环依赖

2. 状态管理

  • 将共享状态放在 Store 中
  • 将组件内部状态保留在组件中
  • 合理使用 computed 和 watch

3. 异步操作

  • 在 actions 中处理异步操作
  • 使用 try-catch 处理错误
  • 提供加载状态和错误状态

4. 性能优化

export const useUserStore = defineStore("user", {
  state: () => ({
    users: [],
    userMap: new Map(), // 使用 Map 提高查找性能
  }),

  getters: {
    getUserById: (state) => (id) => {
      return (
        state.userMap.get(id) || state.users.find((user) => user.id === id)
      );
    },
  },

  actions: {
    setUsers(users) {
      this.users = users;
      // 构建 Map 索引
      this.userMap.clear();
      users.forEach((user) => this.userMap.set(user.id, user));
    },
  },
});

总结

Pinia 为 Vue3 提供了现代化、类型安全的状态管理解决方案。通过合理设计 Store 结构、使用 Getters 和 Actions、实现持久化存储等,可以构建出高效、可维护的状态管理系统。掌握这些概念和最佳实践,将帮助你构建出更好的 Vue 应用。

最近更新:: 2025/8/28 13:12
Contributors: Duke
Prev
Vue3 路由系统
Next
Vue3 性能优化