Vue 3 + Pinia 状态管理最佳实践:从零实现一个高效的全局状态管理方案

Vue 3 + Pinia 状态管理最佳实践:从零实现一个高效的全局状态管理方案

在这里插入图片描述

在 Vue 3 项目中,状态管理是核心之一,合理的状态管理方案可以大幅提升项目的可维护性、可读性以及性能。过去,我们在 Vue 2 时代主要使用 Vuex,但 Vue 3 之后,Pinia 逐渐成为更优的选择。本篇文章将深入探讨 Pinia 的使用方式,并结合 Vue 3 + Vite 进行实战演示。


1. 为什么选择 Pinia?

Pinia 是 Vue 官方推荐的状态管理库,它相较于 Vuex 具有以下优势:
简单易用:API 设计更符合 Vue 3 组合式 API。
类型安全:完美支持 TypeScript,并提供类型推导。
更轻量:没有复杂的 mutations,只使用 actions 和 state。
Vue Devtools 支持:可以在 Vue Devtools 里查看状态变化。


2. 在 Vue 3 项目中集成 Pinia

2.1 初始化 Vue 3 + Vite 项目

我们使用 create-vite 快速搭建 Vue 3 项目:

npm create vite@latest my-vue-app --template vue
cd my-vue-app
npm install

安装 Pinia:

npm install pinia

2.2 在 Vue 项目中注册 Pinia

main.js 中注册 Pinia:

import { createApp } from "vue";
import { createPinia } from "pinia";
import App from "./App.vue";

const app = createApp(App);
app.use(createPinia());
app.mount("#app");

3. 使用 Pinia 管理全局状态

3.1 创建一个 store

src/stores/ 目录下新建 userStore.js

import { defineStore } from "pinia";

export const useUserStore = defineStore("user", {
  state: () => ({
    name: "Alice",
    age: 25,
    isLoggedIn: false,
  }),
  getters: {
    userInfo: (state) => `${state.name} (${state.age}岁)`,
  },
  actions: {
    login(name) {
      this.name = name;
      this.isLoggedIn = true;
    },
    logout() {
      this.name = "";
      this.isLoggedIn = false;
    },
  },
});

说明:

  • state:存储全局状态。
  • getters:类似于 Vuex 的 getters,用来计算衍生状态。
  • actions:类似于 Vuex 的 mutations + actions,可以直接修改 state,并且可以是异步的

4. 在 Vue 组件中使用 Pinia

4.1 在 App.vue 中使用

<script setup>
import { useUserStore } from "./stores/userStore";

const userStore = useUserStore();

function handleLogin() {
  userStore.login("Bob");
}

function handleLogout() {
  userStore.logout();
}
</script>

<template>
  <div>
    <h1>当前用户: {{ userStore.userInfo }}</h1>
    <button @click="handleLogin">登录</button>
    <button @click="handleLogout">退出</button>
  </div>
</template>

说明:

  • 直接使用 userStore.userInfo 获取计算属性。
  • 通过 handleLoginhandleLogout 触发 actions 来修改状态。

5. Pinia 的高级用法

5.1 组合式 API

Pinia 也支持 setup() 形式:

import { defineStore } from "pinia";
import { ref, computed } from "vue";

export const useCartStore = defineStore("cart", () => {
  const items = ref([]);
  
  const totalItems = computed(() => items.value.length);

  function addItem(item) {
    items.value.push(item);
  }

  function removeItem(index) {
    items.value.splice(index, 1);
  }

  return { items, totalItems, addItem, removeItem };
});

5.2 在 Vue 组件中使用

<script setup>
import { useCartStore } from "./stores/cartStore";

const cartStore = useCartStore();

function addNewItem() {
  cartStore.addItem({ id: 1, name: "商品 A", price: 100 });
}

function removeFirstItem() {
  cartStore.removeItem(0);
}
</script>

<template>
  <div>
    <h2>购物车 ({{ cartStore.totalItems }} 件商品)</h2>
    <button @click="addNewItem">添加商品</button>
    <button @click="removeFirstItem">移除第一件商品</button>
  </div>
</template>

6. 持久化存储 Pinia 状态

默认情况下,Pinia 的状态刷新页面会丢失。我们可以使用 pinia-plugin-persistedstate 来实现持久化存储:

npm install pinia-plugin-persistedstate

main.js 配置:

import { createApp } from "vue";
import { createPinia } from "pinia";
import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
import App from "./App.vue";

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

const app = createApp(App);
app.use(pinia);
app.mount("#app");

然后,在 userStore.js 里启用持久化:

export const useUserStore = defineStore("user", {
  state: () => ({
    name: "Alice",
    age: 25,
    isLoggedIn: false,
  }),
  persist: true, // 开启本地存储
});

这样,Pinia 状态会自动存储在 localStorage 中,刷新页面不会丢失。


7. Pinia vs Vuex 选哪个?

特性PiniaVuex
语法风格组合式 API / 选项式 API选项式 API
类型安全✅ 内置支持❌ 需手动定义类型
开发体验✅ 更简单,代码更少❌ 需要定义 mutationsactions
异步操作✅ actions 内部直接支持✅ 需使用 actions
状态持久化✅ 支持 persist 插件❌ 需手动使用 vuex-persist
适用项目适用于 Vue 3 新项目适用于 Vue 2 旧项目

总结

Pinia 更现代化,比 Vuex 轻量、简洁、易维护。
支持 TypeScript 和 Vue 3 组合式 API,适用于新项目。
持久化存储更简单,无需复杂插件。
开发体验优秀,代码更清晰,避免 Vuex 冗余代码。

如果你的项目使用 Vue 3,Pinia 是目前最佳的状态管理方案,值得学习和使用!🔥🚀

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

全栈探索者chen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值