zoukankan      html  css  js  c++  java
  • 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的底层原理?

     

  • 相关阅读:
    Java 简单算法--打印乘法口诀(只使用一次循环)
    Java简单算法--求100以内素数
    ubuntu 16.04 chrome flash player 过期
    java 网络API访问 web 站点
    java scoket (UDP通信模型)简易聊天室
    leetcode1105 Filling Bookcase Shelves
    leetcode1140 Stone Game II
    leetcode1186 Maximum Subarray Sum with One Deletion
    leetcode31 Next Permutation
    leetcode834 Sum of Distances in Tree
  • 原文地址:https://www.cnblogs.com/bruce-w/p/13932294.html
Copyright © 2011-2022 走看看