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的底层原理?

     

  • 相关阅读:
    SpringBoot-容器启动的时候执行一些内容
    Java JVM 启动参数
    leecode刷题(9)-- 有效的数独
    leecode刷题(8)-- 两数之和
    leecode刷题(7)-- 加一
    leecode刷题(6)-- 两个数组的交集II
    leecode刷题(5)-- 只出现一次的数字
    leecode刷题(4)-- 存在重复数组
    leecode刷题(3)-- 旋转数组
    leecode刷题(2)-- 买卖股票的最佳时机
  • 原文地址:https://www.cnblogs.com/bruce-w/p/13932294.html
Copyright © 2011-2022 走看看