源本科技 | 码上会

Vue3 Pinia

2026/04/25
30
0

引言

Pinia 是 Vue.js 生态中新一代的状态管理库,它为 Vue 2 和 Vue 3 应用程序提供了简洁、直观的状态管理解决方案。作为 Vuex 的进化版,Pinia 简化了状态存储的设计,移除了 mutations 概念,支持 TypeScript,并允许模块化地创建和管理跨组件共享的状态。

https://pinia.vuejs.org/zh/

Vuex

Vuex 也是状态管理模式和库。它采用集中式的存储机制来管理应用中所有组件共享的状态(数据),并通过严格的规则保证状态变更的可预测性。在 Vuex 中,状态以 state 对象的形式集中存放,并通过 getter 来获取状态的派生结果;改变状态必须通过 mutation 函数进行同步操作,或通过 action 异步触发变化。

Pinia vs Vuex

  • Mutations 不复存在:Pinia 中只有 stategettersactions

  • Actions 支持同步和异步方法修改 state 状态

  • 与 TypeScript 一起使用,具备可靠的类型推断支持

  • 不再有模块嵌套,仅有 Store 的概念,Store 之间可以相互调用

  • 支持插件扩展,能够便捷实现本地存储等业务常用功能

  • 更加轻量,压缩后体积仅 2 kb 左右

Pinia

安装

执行以下命令完成 Pinia 依赖安装:

npm install pinia

使用

在项目入口文件 main.ts 中引入 Pinia,创建实例并全局挂载使用,完整代码如下:

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

const app = createApp(App);
const pinia = createPinia();

app.use(pinia);
app.mount('#app');

新建项目

  • 为了更好的理解 Pinia 的作用,我们创建一个名为 mypinia 的项目

# 创建项目
npm create vite@latest
# 安装路由
npm install vue-router@4
# 安装组件库
npm install element-plus --save
# 安装状态管理库
npm install pinia
  • 配置 tsconfig.json

{
  "files": [],
  "references": [
    { "path": "./tsconfig.app.json" },
    { "path": "./tsconfig.node.json" }
  ],
  "compilerOptions": {
    "baseUrl": ".", // 基础路径
    "paths": {
      "@/*": ["src/*"] // 映射 @ 到 src 目录
    },
    "types": ["element-plus/global"]
  }
}
  • 修改 tsconfig.app.json

{
  "extends": "@vue/tsconfig/tsconfig.dom.json",
  "compilerOptions": {
    "tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
    "types": ["vite/client"],

    /* Path Mapping */
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    },

    /* Linting */
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "erasableSyntaxOnly": true,
    "noFallthroughCasesInSwitch": true
  },
  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
}
  • 修改 vite.config.ts

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'

// https://vite.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src') // 映射 @ 到 src 目录
    }
  }
})
  • 添加路由配置 src/router/index.ts

import { createRouter, createWebHistory, type RouteRecordRaw } from 'vue-router';

const routes: Array<RouteRecordRaw> = [

];

const router = createRouter({
    history: createWebHistory(),
    routes
});

export default router;
  • 修改 main.ts

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import { createPinia } from 'pinia';
import router from './router'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

const app = createApp(App);
const pinia = createPinia();

app.use(pinia);
app.use(router)
app.use(ElementPlus)
app.mount('#app');