Advertisement

《Vue3 基础知识》Pinia 02 之 项目中从 Vuex 转 Pinia

阅读量:

Vuex 转 Pinia

前言

想了解基础知识可移步《《Vue3 基础知识》Pinia 01 之 基础》

Vue3 项目中增 Pinia,且能与 Vuex4 同时使用。

安装

复制代码
    npm i pinia
    
    
    bash

文件目录

  • 新建文件夹 stores,注意是复数 s。因为 Pinia每个模块都是一个 store
  • 文件 index.jsPinia 初始化文件。其它文件是带 id 的单个 store
复制代码
    # Pinia 目录结构,注意 ID 与文件名匹配
    src
    └── stores
    ├── index.js          # 初始化 Pinia
    ├── gmThemePro.js     # 'gmThemePro' id
    └── user.js           # 'user' id
    
    
    bash

初始化

src/stores/index.js 中初始化 Pinia

复制代码
    import { createPinia } from 'pinia'
    
    const pinia = createPinia()
    
    export default pinia;
    
    
    js:line-numbers

src/main.js 中注册,更多单页面应用在此

复制代码
    import { createApp } from 'vue'
    import App from './App.vue'
    import pinia from './stores' // 导入 /stores/index.js
    
    // 创建 Vue 实例
    const app = createApp(App)
    
    // 注册,注意任何 useXxxStore 都得在此代码之后使用
    app.use(pinia)
    
    
    
    
    js:line-numbers
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/81qMkZLd6fTFp9523wNaHBuJOStQ.png)

改造

Vuex 写法

src\store\modules\user.js 为例,改造为 src\stores\user.js

复制代码
    export default {
    state: () => {
        return {
            avatar: '',
            name: '',
            isManager: false,
            userInfoRole: {}, //用户权限
            funcIds: [], // 功能菜单权限
            treeIds: [], // 目录树权限
            toolIds: [], // 工具条权限
            adminIds: [], //后台管理权限
        }
    },
    mutations: {
        SET_PRIVILEGE: (state, obj) => {
            state.funcIds = obj.funcIds
            state.treeIds = obj.treeIds
            state.toolIds = obj.toolIds
            state.adminIds = obj.privilegeExts
        },
    },
    actions: {
        // 登录
        login({ commit }, obj) {
            // TODO
        },
        // 登出
        logout({ commit }) {
            // TODO
        },
    },
    }
    
    
    js:line-numbers
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/PriQhZsB47CG6SfOlqp3kmTUMNz8.png)

Pinia 写法

  • 使用 defineStore 定义一个 store,且唯一 iduser
  • state 转换为一个箭头函数;
  • getter 中的第一个参数是 state ,访问 state 中的属性用第一个参数。访问其它 getter 直接用 this
  • actions 中的第一个参数 context 删除,所有东西都可用 this 访问;
  • mutationsPinia 中被弃用,可转为 action,将第一个参数 state 删除,所有东西都可用 this 访问;
复制代码
    import { defineStore } from 'pinia'
    
    // 常量名建议以 `use` 开头且以 `Store` 结尾
    export const useUserStore = defineStore('user', {
    state: () => {
        return {
            avatar: '',
            name: '',
            isManager: false,
            userInfoRole: {}, //用户权限
            funcIds: [], // 功能菜单权限
            treeIds: [], // 目录树权限
            toolIds: [], // 工具条权限
            adminIds: [], //后台管理权限
        }
    },
    actions: {
        // 登录
        login(obj) {
            // TODO
        },
        // 登出
        logout() {
            // TODO
        },
        // 设置用户信息,原 mutations 中的 SET_NAME
        setUserInfo( userName, isManager, userInfoRole) {
            // TODO
        },
        // 设置权限信息,原 mutations 中的 SET_PRIVILEGE
        setPrivilege(obj) {
            this.funcIds = obj.funcIds
            this.treeIds = obj.treeIds
            this.toolIds = obj.toolIds
            this.adminIds = obj.privilegeExts
        }
    }
    })
    
    
    js:line-numbers
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/JDLp8ro60emKUEIBc1iQjPMtSgC9.png)

使用

  • 代码第 3 行,先引入 sotre
  • 代码第 9 行,再初始化 sotre
  • 代码第 15,19 行,state/getters/actions 都可用 this.userStore 直接访问;
复制代码
    <script>
    <!-- 第一步: 引入 --> 
    import { useUserStore } from '@/stores/user'
    
    <!-- 第二步: 定义为计算属性 -->
    export default {
    computed: {
        userStore() {
            return useUserStore();
        },
    },
    methods: {
        getUserName() {
            // 直接调属性 name
            return this.userStore.name;
        },
        logout() {
            // 直接调方法 logout
            this.userStore.logout();
        }
    }
    </script>
    
    
    vue:line-numbers
![](https://ad.itadn.com/c/weblog/blog-img/images/2025-08-16/4lLxqra6HFD5CQ8n2pGmA7oMiSZX.png)

全部评论 (0)

还没有任何评论哟~