vuex的解析和用法

vuex是什么?

官方对Vuex一个解释: 是Vue.js 应用程序的状态管理模式 + 库。它充当应用程序中所有组件的集中存储,其规则确保状态只能以可预测的方式改变。

简单地说:vuex就是专门管理所有组件公共状态(公用数据)的一个共享库,专门存储各个需要存储的状态,这种状态是自己可以手动操控,可以预测的。

vuex为什么出现,解决啥问题?

没有vuex的时候,组件通常存在以下问题
存在问题:
1.组件之间的嵌套层级比较深,而且对于兄弟组件根本不起作用
2.组件通讯需要依赖父子组件才能发挥通信作用

负面影响:
1.无法维护的代码
2.组件关系依赖性极高
3.无法维护视图和状态之间独立性

而vuex为我们的代码提供了更多的结构和可维护性,可以解决以上的问题和去除不好影响

什么时候使用vuex?

中大型 SPA 应用构建推荐使用vuex,vuex能更好地处理 Vue 组件之外的状态。

vuex的项目引入

安装依赖包: npm install vuex --save 或 yarn add vuex --save 

vuex的核心

State :用于存储数据
Mutation :更新state中的数据(同步)
Action :在这里异步操作
Getter :对 Store 中的数据进行加工处理形成新的数据,不改变state中的原数据
modules:模块管理

在项目中建一个store仓库,在仓库里面建一个index.js
目录:src/store/index
1.简单版-不拆分模块的使用

store/index.js中使用

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

const store = new Vuex.Store({
  // state相当于data,专门用于定义变量
  state: {
    count: 100,
    addCount: 1,
    multipCount: 2,
    divisionCount: 100,
  },
  // 用于修改state状态值 通过commit触发修改状态
  mutations: {
    //   加
    add(state, data) {
      state.addCount += data;
    },
    // 减
    increment(state, data) {
      state.count -= data;
    },
    // 乘
    multiplication(state, data) {
      state.multipCount *= data;
    },
    // 除
    division(state, data) {
      state.divisionCount %= data;
    },
  },

  /*  
  actions
  用于异步触发 mutations的方法 组件中需要通过dispatch
  
  组件触发方式:
  方式一: this.$store.dispatch('commitAdd', 5)
  方式二:
  import { mapActions } from 'vuex'
  methods: {
 ...mapActions(['commitAdd', 'commitAdd1'])
  }
  直接调用 this.commitAdd(10);
  */
  actions: {
    commitAdd({ commit }, data) {
      commit('add', data);
    },
    commitAdd1({ commit }, data) {
      commit('multiplication', data);
    },
  },

  /*  
  getters
  相当于computed 用于state的状态的加工 但是不改变原来state状态值
  组件中获取加工后的值:
  方式一:this.$store.getters.addNum
  方式二:
  import { mapGetters } from 'vuex'
  computed: {
  ...mapGetters(['addNum'])
  },
  methods:{
    getAddNum(){
      const val = this.addNum();
      console.log(val);
    }
  }
  */
  getters: {
    addNum: (state) => {
      return state.addCount / 2;
    },
  },
});

export default store;

2.复杂版-细分模块
目录结构

在这里插入图片描述
store/index.js

import Vue from 'vue';
import Vuex from 'vuex';
import a from './modules/a';
import b from './modules/b';
import getters from './getters';
Vue.use(Vuex);

const store = new Vuex.Store({
  modules: {
    a,
    b,
  },
  getters,
});

export default store;

store/getters .js

/*  
getters对state状态的加工
getters
  相当于computed 用于state的状态的加工 但是不改变原来state状态值
  组件中获取加工后的值:
  方式一:this.$store.getters.addAcountANum
  方式二:
  import { mapGetters } from 'vuex'
  computed: {
  ...mapGetters(['addAcountANum','addBcountBNum'])
  },
  methods:{
    getAddNum(){
      const valA = this.addAcountANum();
      const valB = this.addBcountBNum();
      console.log(valA,valB);
    }
  }
*/
const getters = {
  addAcountANum: (state) => {
    return state.a.addAcountA / 2;
  },
  addBcountBNum: (state) => {
    return state.b.addBcountB / 2;
  },
};
export default getters;

store/modules/a.js

const A = {
  // state相当于data,专门用于定义变量
  state: {
    countA: 100,
    addAcountA: 1,
    multipcountA: 2,
    divisioncountA: 100,
  },
  // 用于修改state状态值 通过commit触发修改状态
  mutations: {
    //   加
    addA(state, data) {
      state.addAcountA += data;
    },
    // 减
    incrementA(state, data) {
      state.countA -= data;
    },
    // 乘
    multiplicationA(state, data) {
      state.multipcountA *= data;
    },
    // 除
    division(state, data) {
      state.divisioncountA %= data;
    },
  },

  /*  
  actions
  用于异步触发 mutations的方法 组件中需要通过dispatch
  
  组件触发方式:
  方式一: this.$store.dispatch('commitaddA', 5)
  方式二:
  import { mapActions } from 'vuex'
  methods: {
 ...mapActions(['commitaddA', 'commitaddA1'])
  }
  直接调用 this.commitaddA(10);
  */
  actions: {
    commitaddA({ commit }, data) {
      commit('addA', data);
    },
    commitaddA1({ commit }, data) {
      commit('multiplicationA', data);
    },
  },
};

export default A;

store/modules/b.js

const B = {
  // state相当于data,专门用于定义变量
  state: {
    countB: 100,
    addBcountB: 1,
    multipcountB: 2,
    divisioncountB: 100,
  },
  // 用于修改state状态值 通过commit触发修改状态
  mutations: {
    //   加
    addB(state, data) {
      state.addBcountB += data;
    },
    // 减
    incrementB(state, data) {
      state.countB -= data;
    },
    // 乘
    multiplicationB(state, data) {
      state.multipcountB *= data;
    },
    // 除
    division(state, data) {
      state.divisioncountB %= data;
    },
  },

  /*  
    actions
    用于异步触发 mutations的方法 组件中需要通过dispatch
    
    组件触发方式:
    方式一: this.$store.dispatch('commitaddB', 5)
    方式二:
    import { mapActions } from 'vuex'
    methods: {
   ...mapActions(['commitaddB', 'commitaddB1'])
    }
    直接调用 this.commitaddB(10);
    */
  actions: {
    commitaddB({ commit }, data) {
      commit('addB', data);
    },
    commitaddB1({ commit }, data) {
      commit('multiplicationB', data);
    },
  },
};

export default B;

在main.js中全局引入和使用

//路径根据实际文件夹路径来即可
import store from './store';

new Vue({
  render: (h) => h(App),
  store,
}).$mount('#app');

总结:
1、使用 Vuex 统一管理状态的好处:
① 能够在 vuex 中集中管理共享的数据,易于开发和后期维护
② 能够高效地实现组件之间的数据共享,提高开发效率
③ 存储在 vuex 中的数据都是响应式的,能够实时保持数据与页面的同步

扫描二维码关注公众号,回复: 13419591 查看本文章

2、触发vuex中的4个的对象都有2中方式
方式一:


State       this.$store.state.全局数据名称
Mutation    this.$store.commit('Mutation中的方法名')
Ation       this.$store.dispatch('Action中的方法名')
Getters     this.$store.getters.名称

方式二:
组件导入使用

import { mapState, mapMutations, mapActions, mapGetters } from 'vuex'
直接在 计算属性或者methods 中使用展开运算符/扩展运算符(...)就可以了

 computed: {
    ...mapState(['count']),
    ...mapGetters(['showNum'])
  },
  methods: {
    ...mapMutations(['sub', 'subN']),
    ...mapActions(['subAsync', 'subNAsync']),
  }

以上代码中 count和showNum可以直接当成计算属性使用,而sub、subN、subAsync、subNAsync可以直接当成方法使用

3、使用注意:
① 不要在组件中直接使用 this.$store.state.全局数据名称取更改 state中的数据,如果直接更改,调试工具监测不到数据更改
② 只有 mutations 中定义的函数,才有权利修改 state 中的数据,不要在 mutations 函数中,执行异步操作(调试工具监测不到数据更改)
③ 在 actions 中,不能直接修改 state 中的数据,必须通过 context.commit() 触发某个 mutation 才行

猜你喜欢

转载自blog.csdn.net/qq_44472790/article/details/119491462