Vuex的通俗详解

Vuex

  1. 什么是Vuex?

    Vuex是一种最好的非父子组件传值的方案
    官方解释:一个公共的状态管理V

    其实Vuex就是一个公共的内存对象,把所有组件需要共有的状态放在一个公共的内存空间中,

    并且给每一个状态做了一个数据劫持(给每一个状态添加了一个getter和setter方法)。
  2. Vuex的基本使用

    1. 安装

      $ cnpm install Vuex -S
      or
      $ yarn add Vuex
    2. 引入插件( 在store文件中中index.js写入 )

      import Vuex from 'vuex'
    3. 使用Vuex( 在store文件中中index.js写入 )

      Vue.use(Vuex)
    4. 创建公共的内存对象( 在store文件中中index.js写入 )

      const store = new Vuex.Store({

      })
    5. 将Vuex导出挂载到Vue身上( 在main.js写入 )

      new Vue({
      store
      })
  3. Vuex中常用配置项 ( 都是对象 )

    • state 存储公共的状态

    • mutations 修改公共的状态

      mutantions里面的函数有两个参数
      参数1:state
      参数2:传递的参数
    • actions 处理异步

      actions里面的函数有两个参数
      参数1:是一个对象{ commit dispatch   state getters }
      参数2:传递参数
    • modules 公共状态私有化

      由于使用单一状态树,应用的所有状态会集中到一个比较大的对象。当应用变得非常复杂时,
      store 对象就有可能变得相当臃肿。( 在store文件夹下面创建多个子文件,每个文件都是一个独立得模块 )
      //创建单独的子模块( 可以在store文件夹下面创建 ) 并写入
      export default{
          state:{
              childenProduct : '子模块状态',
          },
          actions : {
      ​
          },
          mutations : {
      ​
          },
          getters : {
              
          },
          //实现子模块的私有化.
          namespaced:true
          //如果添加上上述属性,访问子模块中的方法的时候  需要  子模块名称/方法名称
      }
      ​
      //在主模块中引入
      import 名称 from './childStore'
      //在 主模块 modules 里面注册上名称即可
      modules : { 
          名称,
      }
          
      //组件中使用
      {{this.$store.state.名称.状态属性}}
          
      ​
          
      //namespaced:true 添加后  访问子模块中的方法的时候  需要  子模块名称/方法名称
        methods: {
          ...mapMutations({
            //handleBtn : 'product/handleLike'  //访问的是子模块的handleLike
            handleBtn : 'handleLike'  //访问的是主模块的handleLike
          }),
        }
    • getters 公共状态计算属性 等价于 computed 依赖于state中的状态

      getters等于computed是一个计算属性,当所依赖state属性发生改变的时候就会触发getters里面的方法
      getters里面的函数都会有一个参数这个参数state ,当前函数用来依赖于state中的属性.
      getters : {
          count(state){
             let res = Number(state.num1) + Number(state.num2);
             console.log(res);
             return res;
             
          }
        }
  4. Vuex数据传递的流程

    1、通过new Vuex.Store()创建一个仓库 state是公共的状态,state--->components渲染页面
    2、在组件内部通过this.$store.state.属性 来调用公共状态中的state,进行页面的渲染。
    3、当组件需要修改数据的时候,必须遵循单向数据流。通过this.$store.dispatch来触发actions中的方法
    4、actions中的每个方法都会接受一个对象 这个对象里面有一个commit方法,用来触发mutations里面的方法
    5、mutations里面的方法用来修改state中的数据 mutations里面的方法都会接收到2个参数
       一个是store中的state 另外一个是需要传递到参数
    6、当mutations中的方法执行完毕后state会发生改变,因为vuex的数据是响应式的 所以组件的状态也会发生改变

     

    操作流程

    1. 组件内部进行操作

      methods : {
          handle(){
              this.$store.dispatch('handleActionAdd','传递过来的参数数据');
          }
      }
    2. 用上述dispatch执行actions里面的handleActionAdd方法:

      actions : {
          //解耦commit方法,params是传递过来的数据
          handleActionAdd({commit},params){
            //commit方法执行mutaions里面的方法修改状态
            commit('handleMutationsAdd',params);
          }
      },
       
    3. mutions内部的方法

      mutations : {
          handleMutationsAdd(state,params){
            //第一个参数是一个state对象,第二个参数是传递的数据
            state.num1 = params;
          }
        }

    注意:不要在组件内部修改store里面的数据

    为什么必须遵循数据流程:
    1:更加明确的追踪到状态的变化
    2:通过vue-devtools来进行时间旅行的状态监测
    3: 如果涉及到数据的异步获取( 在actions里面做axios数据请求以及业务逻辑处理 ),我们必须要走vuex的数据流程

    补充: 如果不涉及到异步数据处理我们可以跨越actions直接在组件内部 用this.$store.commit('mutations里面的方法')即可
    eg:

        this.$store.commit('handleMutationsInputChange',e.target.value);
  5. 辅助函数

    辅助函数就是通过映射的关系将Vuex中的方法或者状态映射给组件的某一属性,辅助函数的返回值是一个对象

    ( 1 ) state的辅助函数mapState

    <h2>{{$store.state.a}}</h2>
    <h2>{{$store.state.b}}</h2>
    <h2>{{$store.state.b}}</h2>
    <h2>{{$store.state.c}}</h2>
    <!-- 如上: 组件中出现大量状态,这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键 -->
    import {mapState} from 'vuex';
    //mapState函数绑定在组件中的computed上面,
    export default {
      name : 'app',
      //基本语法 : 弊端:  mapState会占用computed 让组件中的其他计算无法添加  ->  后面讲解语法扩展
      computed : mapState(['a','b','c','d'])
    }
    //这样组件中直接使用 {{a}}   {{b}}  {{c}}  {{d}} 即可
    /*
        <h2>{{a}}</h2>
        <h2>{{b}}</h2>
        <h2>{{c}}</h2>
        <h2>{{d}}</h2>
    */
    ​
    ​
    ​
    //computed : mapState(['a','b','c','d']) mapState会占用computed 让组件中的其他计算无法添加,可以选用 ...对象扩展符号进行写入
    export default {
      name : 'app',
      computed : {
          //可以选用 ...对象扩展符号进行写入
          ...mapState({
              // 箭头函数可使代码更简练  ( 可以对复杂状态名的重置  {{ nameA }}即可 )  
              nameA : state => state.a,
              nameB : state => state.b,
              nameC : state => state.c,
              nameD : state => state.d,
          })
      }
    }
    ​
    /*
        <h2>{{nameA}}</h2>
        <h2>{{nameB}}</h2>
        <h2>{{nameC}}</h2>
        <h2>{{nameD}}</h2>
    */

    ( 2 ) mutations的辅助函数 mapMutations

    import { mapMutations } from 'vuex';
    //mapMutations辅助函数必须映射在组件的methods上面
    //<button @click="handleUpdataA">点击</button>
    //handleUpdateA 函数就是 store文件夹index.js中 mutations里面的方法
    //语法1:  后面是数组
    methods: {
      ...mapMutations(['handleUpdataA']),
    }
      
      
    //语法2:  后面是对象( 推荐 )
    //<button @click="handleBtn">点击</button>
    methods: {
       ...mapMutations({
         handleBtn : 'handleUpdataA'
       })
    }

    ( 3 ) actions的辅助函数 mapActions

    import { mapActions } from 'vuex';
    //mapMutations辅助函数必须映射在组件的methods上面
    //<button @click="handleUpdataA">点击</button>
    //handleUpdateA 函数就是 store文件夹index.js中 actions里面的方法
    //语法1:  后面是数组
    methods: {
      ...mapActions(['handleUpdataA']),
    }
      
      
    //语法2:  后面是对象( 推荐 )
    //<button @click="handleBtn">点击</button>
    methods: {
       ...mapActions({
         handleBtn : 'handleUpdataA'
       })
    }

    ( 4 ) getters的辅助函数 mapGetters

    import {mapGetters} from 'vuex';
    //注:mapGetters必须映射到 computed 上面
    //语法1: 数组
    computed : {
        ...mapGetters(['handle1','handle2'])
    }
    ​
    //语法2: 对象
    computed : {
        ...mapGetters({
            handle : 'handleGetter'
        })
    }

     

Vuex常见问题

1: Vuex的数据传递流程
2: Vuex的数据刷新浏览器丢失了如果解决
3:什么时候用到Vuex
a:并不是所有的项目都用到vuex
b:只有复杂的中大型项目才会用到vuex
c:如果小型项目用到vuex会导致项目运行速度特别慢
4:Vuex中常用的配置项是哪些?每一个的作用是什么
5:Vuex的底层原理?

 

原文地址:https://www.cnblogs.com/bruce-w/p/13932294.html