• vuex和pinia转态管理工具介绍


    一、介绍

    相同点: 都是Vue.js的状态管理工具

    不同点:

    区别PiniaVuex
    支持Vue2和Vue3都支持Vue3写法需要额外配置
    Mutation只有 state, getter 和 action,无Mutationaction异步、Mutation 同步
    actionaction支持同步和异步action异步、Mutation 同步
    Typescript良好的Typescript支持需要额外的配置
    模块嵌套不需要嵌套模块,符合 Vue3 的 Composition api,让代码扁平化需要
    模块嵌套不需要嵌套模块,符合 Vue3 的 Composition api,让代码扁平化Vuex中如果数据过多,我们通常分模块来进行管理
    模块嵌套不需要嵌套模块,符合 Vue3 的 Composition api,让代码扁平化,pinia中每个store都是独立的,互相不影响Vuex中如果数据过多,我们通常分模块来进行管理
    体积体积非常小,只有1KB左右体积大
    插件扩展支持插件来扩展自身功能不能
    服务端渲染支持服务端渲染不能

    总结:pinia的优点

    • 支持Vue3 和 Vue2,完整的 ts 的支持;
    • 足够轻量,压缩后的体积只有1kb左右;
    • 去除 mutations,只有 state,getters,actions;
    • actions 支持同步和异步;
    • 代码扁平化没有模块嵌套,只有 store 的概念,store 之间可以自由使用,每一个store都是独立的 无需手动添加store,store 一旦创建便会自动添加;
    • 支持插件来扩展自身功能|
    • 支持服务端渲染

    注意点

    pina的使用,有时候动态路由一般需要在beforeEach中去做拦截处理,把后端传过来的路由数据存入,页面第一次也会去走一次router文件,由于pinia没有挂载到vue上面,导致报错,

    问题: Uncaught Error: [🍍]: getActivePinia was called with no active Pinia. Did you forget to install pinia?
    这个问题代表当前正在使用pinia; 但是pinia 还没有挂载成功

    做法就是新建一个js文件,然后在js文件创建初始化,然后导出,然后分别在main和使用路由守卫的地方去引入。

    二、使用

    1、pinia使用

    • 安装
     npm install pinia@next
    
    • 1
    • vue3项目下创建一个 Pinia store,例如counterStore.js
    import { defineStore } from 'pinia';
    
    export const useCounterStore = defineStore({
      id: 'counter',
      state: () => ({
        count: 0,
      }),
      getters: {
        doubleCount() {
          return this.count * 2;
        },
      },
      actions: {
        increment() {
          this.count++;
        },
        decrement() {
          this.count--;
        },
      },
    });
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 引入 Pinia 到 Vue 应用中
    // main.js
    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')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 在页面上使用
    <template>
      <div>
        <p>Count: {{ counter.count }}</p>
        <p>Double Count: {{ counter.doubleCount }}</p>
        <button @click="counter.increment">Increment</button>
        <button @click="counter.decrement">Decrement</button>
      </div>
    </template>
    
    <script>
    import { useCounterStore } from '@/counterStore.js';
    
    export default {
      setup() {
        const counter = useCounterStore();
    
        return { counter };
      },
    };
    </script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    2、Vuex使用

    • 安装
    npm install vuex
    
    
    • 1
    • 2
    • Vue 2 项目中创建一个 Vuex store,例如 store.js 的文件
    import Vue from 'vue';
    import Vuex from 'vuex';
    
    Vue.use(Vuex);
    
    export default new Vuex.Store({
      state: {
        count: 0,
      },
      mutations: {
        increment(state) {
          state.count++;
        },
        decrement(state) {
          state.count--;
        },
      },
      actions: {
        increment(context) {
          context.commit('increment');
        },
        decrement(context) {
          context.commit('decrement');
        },
      },
      getters: {
        doubleCount(state) {
          return state.count * 2;
        },
      },
    });
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 主Vue实例中引入并配置store。
    // main.js
    import Vue from 'vue';
    import App from './App.vue';
    import store from './store';
     
    new Vue({
      store,
      render: h => h(App)
    }).$mount('#app');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 在页面上使用
    <template>
      <div>
        <p>Count: {{ $store.state.count }}</p>
        <p>Double Count: {{ doubleCount }}</p>
        <button @click="increment">Increment</button>
        <button @click="decrement">Decrement</button>
      </div>
    </template>
    
    <script>
    export default {
      computed: {
        doubleCount() {
          return this.$store.getters.doubleCount;
        },
      },
      methods: {
        increment() {
          this.$store.dispatch('increment');
        },
        decrement() {
          this.$store.dispatch('decrement');
        },
      },
    };
    </script>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 优化,有时候需要引入很多个,此时可以根据自动批量导入JS模块
      在这里插入图片描述
    import Vue from 'vue'
    import Vuex from 'vuex';
    Vue.use(Vuex);
    
    //导入modules所有模块
    const modulesFiles = require.context('./modules', true, /\.js$/);
    
    const modules={};
    modulesFiles.keys().forEach(key => {
        const module= modulesFiles(key).default;
    	const moduleName=key.slice(2,-3);//以文件名为模块名,./user.js 截取(user)
        modules[moduleName]=module
    });
    
    const store=new Vuex.Store({
    	modules,
    	
    });
    export default store
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 例如user.js的写法
    const state = {
    	name: '测试'
    };
    const getters = {
    	getName: state => state.name
    }
    const mutations = {
    	SET_NAME(state, val) {
    		state.name = val;
    	}
    };
    const actions = {
    
    	setName({commit}, val) {
    		return new Promise((resolve, reject) => {
    			setTimeout(() => {
    				commit('SET_NAME', val);
    				resolve()
    
    			}, 100)
    		}).catch(err => {
    			reject(err)
    		})
    	}
    };
    
    export default {
    	namespaced: true,
    	state,
    	mutations,
    	actions,
    	getters
    };
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 自动批量导入JS模块:在页面上使用
     export default {
      mounted(){
    		获取user  state里面的数据
    		this.$store.state.user.name //测试
    		
    		修改user  mutations 的数据
    		this.$store.commit(‘user/SET_NAME’,‘修改’)
    		
    		获取user getters
    		this.$store.getters[‘user/getName’]
             
            异步修改state里面的数据
    		await this.$store.dispatch(‘user/setName’,‘修改’)
      }		
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    Nacos-配置中心基本使用
    与C共舞:让编译更顺滑(2)
    137.只出现一次的数字II
    SpringSecurity系列——访问控制之基于方法的控制day6-3(源于官网5.7.2版本)
    【Kubernetes | Pod 系列】Pod 的基本管理(3)——对 Pod 的删除与修改
    mysql存储过程和函数
    可变形卷积(DCN)
    win11改成win7界面的设置方法
    老师设计的库CRC计算
    数据结构之查找
  • 原文地址:https://blog.csdn.net/Smile_666666/article/details/138078916