当前位置: 首页 > news >正文

Pinia 实战指南:Vue 3 的新一代状态管理工具

1. 什么是 Pinia?

Pinia 是 Vue 官方推荐的状态管理库,专为 Vue 3 构建,使用 TypeScript 编写,API 设计现代、简洁。Pinia 是 Vuex 的“精神继任者”,其设计理念更加贴近 Composition API 和模块化思维。

它主要用于:

  • 在多个组件间共享状态
  • 解耦复杂逻辑
  • 替代 props 和 emit 的繁琐传参
  • 管理全局数据(用户信息、权限、缓存配置等)

2. 适用场景:什么时候该用 Pinia?

Pinia 最适合用于中大型 Vue 3 项目,尤其是在以下场景中非常适用:

  1. 组件之间共享数据(非父子)
    1. 比如:用户登录信息、主题色、系统配置等
  2. 需要持久化状态或异步加载数据
    1. 比如:菜单列表、权限控制、缓存设置、token 等
  3. 状态变化需要在多个页面响应
    1. 比如:购物车、订单状态、通知数目等
  4. 避免 props 和 emit 层层传递造成的组件嵌套混乱

3. 安装与基本使用

3.1 安装 Pinia 
npm install pinia
3.2 注册 Pinia
// main.ts
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');

 4. 📂 创建一个 store(🌰:用户信息)

Pinia 使用 defineStore 来定义一个 store,useStore 用于在组件中访问这个 store。

// stores/user.ts
import { defineStore } from 'pinia';

export const useUserStore = defineStore('user', {
  state: () => ({
    token: '',
    userInfo: null as null | { id: string; name: string },
    // 定义其他状态
  }),
  getters: {
    isLoggedIn: (state) => !!state.token,
  },
  actions: {
    setToken(token: string) {
      this.token = token;
    },
    async fetchUserInfo() {
      const res = await fetch('/api/user');
      this.userInfo = await res.json();
    },
    logout() {
      this.token = '';
      this.userInfo = null;
    },
    // 定义其他方法
  },
});
4.1 在组件中使用
<script setup lang="ts">
import { useUserStore } from '@/stores/user';

const userStore = useUserStore();

// 使用状态
console.log(userStore.token);

// 修改状态
userStore.setToken('new-token');

// 调用异步方法
await userStore.fetchUserInfo();
</script>
 4.2 Composition 风格:setup 语法糖

也可以使用 defineStore() 的 setup 模式,结合 Composition API:

// stores/counter.ts
import { defineStore } from 'pinia';
import { ref, computed } from 'vue';

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0);
  const double = computed(() => count.value * 2);
  function increment() {
    count.value++;
  }

  return { count, double, increment };
});

更适合小模块的组合与拆分。

5. 实用技巧

5.1 状态持久化(如登录信息)
import { defineStore } from 'pinia';
import { useStorage } from '@vueuse/core';

export const useUserStore = defineStore('user', () => {
  const token = useStorage('token', '');
  return { token };
});

🔐 结合 @vueuse/core 可轻松实现持久化,甚至支持 localStorage/sessionStorage 切换。

那什么是 @vueuse/core 呢?

一句话介绍:其是一个专为 Vue 3(支持 Composition API)设计组合式函数库,提供了大量的高质量、响应式的工具函数,极大简化日常开发。本质是一套帮助我们写 Vue 逻辑更省心的「组合式函数工具箱」,有点像是 Vue 世界里的 “Lodash + Hooks + 工具函数合集”。

安装方式

npm install @vueuse/core

然后直接在 Vue 组件里使用,比如:

1、useLocalStorage - 响应式 localStorage

import { useLocalStorage } from '@vueuse/core'

const token = useLocalStorage('token', '')
token.value = 'abc123'  // 自动同步到 localStorage

在 Pinia 里用它可以实现状态持久化,比手写 localStorage 更优雅。

2、useDark - 黑夜模式切换

import { useDark, useToggle } from '@vueuse/core'

const isDark = useDark() // 根据系统或浏览器默认模式
const toggleDark = useToggle(isDark)

toggleDark() // 调用切换深色/浅色

3、useDebounceFn - 函数防抖

import { useDebounceFn } from '@vueuse/core'

const search = useDebounceFn((value) => {
  console.log('搜索:', value)
}, 300)

4、useEventListener - 监听任意事件

import { useEventListener } from '@vueuse/core'

useEventListener(window, 'resize', () => {
  console.log('窗口大小改变')
})

注意事项:

  1. 必须 Vue 3 项目,Composition API 风格。
  2. useXxx() 函数 都是响应式封装,不要解构。
  3. 某些函数依赖 DOM API,需要运行在浏览器环境中(如 SSR 要注意)。
  4. 可配合 Pinia、Vant、Element Plus、Vue Router 等一同使用,提升开发效率和可维护性

🆚 和 Lodash、手写工具函数对比

对比项Lodash手写工具@vueuse/core
响应式支持❌ 无❌ 无✅ 有
Vue 生态集成
封装程度中等看自己写得怎么样✅ 极高
使用成本简单灵活但易出错简单、安全、组合性强
5.2  解耦模块 & 动态加载 store

使用时再加载模块,避免初始时注册过多模块:

import { storeToRefs } from 'pinia';
const userStore = useUserStore();
const { token } = storeToRefs(userStore);
5.3 热更新支持(开发时体验超好)
if (import.meta.hot) {
  import.meta.hot.accept(acceptHMRUpdate(useUserStore, import.meta.hot));
}

6. 📈 优缺点

优势描述
更轻量没有 mutation 的冗余设计,api 更简洁
类型推导好TypeScript 支持优秀,代码提示一流
支持组合式与 Composition API 完美兼容
更易模块化Store 设计天然支持按需加载
响应式天然继承状态就是 ref/reactive 对象
热更新支持HMR 默认支持,无需额外配置
状态透明就是普通变量,更容易调试
缺点描述
Vue 2 不兼容只能用于 Vue 3 项目
插件生态还不如 Vuex 丰富一些高级场景还需手写或三方库
需要习惯新范式对 Vuex 用户来说需要转变 mindset
6.1 与 Vuex 的对比
维度VuexPinia
API 风格传统、模块多(state、getter、mutation、action)简洁(只有 state、getter、action)
响应式支持Vue2 风格响应式Composition API 响应式
TypeScript支持但不自然极佳
模块管理需要注册 module文件即模块
状态定义state 是对象函数state 是 ref/reactive
调用方式commit + dispatch直接方法调用
插件生态丰富,官方插件多逐渐完善中
6.2 使用注意点 

1、Pinia 是响应式的,当状态发生变化时,相关的视图会自动更新。但不是自动深监听:使用 ref({}) 时要注意解构导致丢失响应式。

2、避免解构 state 内部变量,可以使用 storeToRefs:

const { token } = storeToRefs(useUserStore());

3、在非组件中使用 Store:直接调用 useXXXStore() 即可,前提是 pinia 已注册。

4、不要在 defineStore 外部使用 store 实例,否则可能影响响应式。

相关文章:

  • Springboot同时支持不同的数据库,Oracle,Postgresql
  • 【AI学习】初步了解TRL
  • pycharm 添加 pyside6 插件并修改 Ui 样式
  • 在亚马逊云科技上使用n8n快速构建个人AI NEWS助理
  • 与Linux操作系统相关的引导和服务
  • 图论:多源最短路
  • 【LeetCode77】组合
  • JS dom节点
  • Django分页教程及示例
  • 【Kafka基础】topics命令行操作大全:高级命令解析(2)
  • 深度解析 C# 中介者模式:设计与实战应用
  • vue3实现markdown工具栏的点击事件监听
  • Python设计模式:构建模式
  • 检测手机插入USB后,自动启动scrcpy的程序
  • C++建造者模式进化论
  • leetcode155.最小栈
  • 【lodash的omit函数详解 - 从入门到精通】
  • Solidity智能合约漏洞类型与解题思路指南
  • 用Python 还是C\C++ 开发嵌入式物联网项目
  • 使用Python快速删除Docker容器、镜像和存储内容
  • 河南信阳:对违规吃喝问题不遮丑不护短,露头就打、反复敲打
  • 收到延期付款利息,该缴纳增值税吗?
  • 上海高院与上海妇联签协议,建立反家暴常态化联动协作机制
  • 向猫学习禅修之后,你会发现将生活降格为劳作是多么愚蠢
  • 外交部:反对美方人士发表不负责任谬论
  • 京东CEO许冉:外卖日单量接近2000万单,看到外卖对平台拉动和转化效应