【Pinia】Pinia和Vuex对比

Pinia 是 Vue 官方团队成员专门开发的一个全新状态管理库,并且 Vue 的官方状态管理库已经更改为了 Pinia。 在 Vuex 官方仓库中也介绍说可以把 Pinia 当成是不同名称的 Vuex 5,这也意味不会再出 5 版本了。

优点

  1. 更加轻量级,压缩后提交只有1.6kb。

  2. 完整的 TS 的支持,Pinia 源码完全由 TS 编码完成。

Pinia 在与 TS 一起使用时,具有可靠的类型判断支持;Vuex 之前对 TS 的支持很不友好。

  1. 移除 mutations,只剩下 state 、 actions 、 getters,在store内部直接使用this使用state里的数据。

一旦 store 被实例化,就可以直接在 store 上访问 state、getters 和 actions 中定义的任何属性;而在使用 Vuex 的时候,更改状态需要纠结选取 mutation 还是 action。

  1. 不再有 Vuex 里多个 modules 的嵌套结构,可以定义多个 store 并灵活使用。

  2. 不会再有module的命名空间的概念,不需要记住他们的复杂关系。

  3. 支持服务端渲染(SSR)。

  4. 更友好的代码分割机制。

  5. 提供了 Pinia 状态持久化。配置 | Pinia Plugin Persistedstate

举例说明

针对第4点

Pinia版本:假设我们有一个购物车应用,需要管理用户信息和购物车商品信息,可以用两个 Store 来实现。

javascript 复制代码
// userStore.js
import { defineStore } from 'pinia';
export const useUserStore = defineStore('user', {
  state: () => ({
    name: '',
    age: 0,
  }),
  actions: {
    updateName(newName) {
      this.name = newName;
    },
  },
});

// cartStore.js
import { defineStore } from 'pinia';
export const useCartStore = defineStore('cart', {
  state: () => ({
    items: [],
  }),
  actions: {
    addItem(item) {
      this.items.push(item);
    },
  },
});

Vuex版本:在组件中,通过 this.$store 来访问状态,需要通过命名空间来区分模块,例如 this.$store.state.user.namethis.$store.commit('cart/addItem', item)

javascript 复制代码
// store.js
import { createStore } from 'vuex';
export default createStore({
  modules: {
    // 用户
    user: {
      state: {
        name: '',
        age: 0,
      },
      mutations: {
        updateName(state, newName) {
          state.name = newName;
        },
      },
    },
    // 购物车
    cart: {
      state: {
        items: [],
      },
      mutations: {
        addItem(state, item) {
          state.items.push(item);
        },
      },
    },
  },
});

针对第5点

Vuex 中,如果没有命名空间,多个模块有相同名称的方法,如模块A和模块B都有updateName,使用起来会冲突,因为 Vuex 不知道要调用哪个模块的 updateName

javascript 复制代码
// 模块 A
mutations: {
  updateName(state, newName) {
    state.name = newName;
  },
}

// 模块 B
mutations: {
  updateName(state, newName) {
    state.name = newName;
  },
}

通过命名空间namespaced: true,可以将每个模块的作用域限制在模块内部,避免冲突。

javascript 复制代码
// 模块 A
namespaced: true, 
mutations: {
  updateName(state, newName) {
    state.name = newName;
  },
}

// 模块 B
namespaced: true, 
mutations: {
  updateName(state, newName) {
    state.name = newName;
  },
}


// 组件中使用
this.$store.commit('moduleA/updateName', 'John');
this.$store.commit('moduleB/updateName', 'Jane');

当然,在 pinia 中没有模块化的概念了,就更不存在需要使用命名空间了。

相关推荐
LaughingZhu6 小时前
Product Hunt 每日热榜 | 2026-05-21
前端·人工智能·经验分享·chatgpt·html
怕浪猫6 小时前
Electron 开发实战(一):从零入门核心基础与环境搭建
前端·electron·ai编程
小鹏linux7 小时前
Ubuntu 22.04 部署开源免费具有精美现代web页面的Casdoor账号管理系统
linux·前端·ubuntu·开源·堡垒机
前端若水8 小时前
会话管理:创建、切换、删除对话历史
前端·人工智能·python·react.js
Bigger8 小时前
mini-cc:一个轻量级 AI 编程助手的诞生
前端·ai编程·claude
涵涵(互关)8 小时前
Naive-ui树型选择器只显示根节点
前端·ui·vue
BY组态8 小时前
Ricon组态系统最佳实践:从零开始构建物联网监控平台
前端·物联网·iot·web组态·组态
BY组态9 小时前
Ricon组态系统vs传统组态软件:为什么选择新一代Web组态平台
前端·物联网·iot·web组态·组态
SoaringHeart9 小时前
Flutter进阶:OverlayEntry 插入图层管理器 NOverlayZIndexManager
前端·flutter
放下华子我只抽RuiKe59 小时前
React 从入门到生产(四):自定义 Hook
前端·javascript·人工智能·深度学习·react.js·自然语言处理·前端框架