zoukankan      html  css  js  c++  java
  • Vuex入门(2)_state,mapState,...mapState对象展开符详解

    vuex的几个关键配置

    1.state

    state是什么?

      定义:state(vuex) ≈ data (vue)

      vuex的state和vue的data有很多相似之处,都是用于存储一些数据,或者说状态值.这些值都将被挂载 数据和dom的双向绑定事件,也就是当你改变值的时候可以触发dom的更新.

      虽然state和data有很多相似之处,但state在使用的时候一般被挂载到子组件的computed计算属性上,这样有利于state的值发生改变的时候及时响应给子组件.如果你用data去接收$store.state,当然可以接收到值,但由于这只是一个简单的赋值操作,因此state中的状态改变的时候不能被vue中的data监听到,当然你也可以通过watch $store去解决这个问题

    请用computed去接收state,如下

    //state.js
    let state = {
      count: 1,
      name: 'dkr',
      sex: '男',
      from: 'china'
    }
    export default state
    <template>
      <div id="example">
        <button @click="decrement">-</button>
        {{count}}
        {{dataCount}}
        <button @click="increment">+</button>
      </div>
    </template>
    <script>
    export default {
      data () {
        return {
          dataCount: this.$store.state.count //用data接收
        }
      },
      computed:{
        count(){
          return this.$store.state.count //用computed接收
        }
      }
      methods: {
        increment () {
          this.$store.commit('increment')
        },
        decrement () {
          this.$store.commit('decrement')
        }
      }
    }
    </script>

    结果如下,用data接收的值不能及时响应更新,用computed就可以

    2.mapState 辅助函数

      mapState是什么?

      表面意思:mapState是state的辅助函数

    实际作用:当一个组件需要获取多个状态时候,将这些状态都声明为计算属性会有些重复和冗余。为了解决这个问题,我们可以使用 mapState 辅助函数帮助我们生成计算属性,让你少按几次键

      在使用mapState之前,要导入这个辅助函数

    import { mapState } from 'vuex'

    然后就是使用方式了

    <template>
      <div id="example">
        <button @click="decrement">-</button>
        {{count}}
        {{dataCount}}
        <button @click="increment">+</button>
        <div>{{sex}}</div>
        <div>{{from}}</div>
        <div>{{myCmpted}}</div>
      </div>
    </template>
    <script>
    import { mapState } from 'vuex'
    export default {
      data () {
        return {
          str: '国籍',
          dataCount: this.$store.state.count
        }
      },
      computed: mapState({
        count: 'count', // 第一种写法
        sex: (state) => state.sex, // 第二种写法
        from: function (state) { // 用普通函数this指向vue实例,要注意
          return this.str + ':' + state.from
        },
        // 注意下面的写法看起来和上面相同,事实上箭头函数的this指针并没有指向vue实例,因此不要滥用箭头函数
        // from: (state) => this.str + ':' + state.from
        myCmpted: function () {
          // 这里不需要state,测试一下computed的原有用法
          return '测试' + this.str
        }
      }),
      methods: {
        increment () {
          this.$store.commit('increment')
        },
        decrement () {
          this.$store.commit('decrement')
        }
      },
      created () {
        // 写个定时器,发现computed依旧保持了只要内部有相关属性发生改变不管是当前实例data中的改变,还是vuex中的值改变都会触发dom和值更新
        setTimeout(() => {
          this.str = '国家'
        }, 1000)
      }
    }
    </script>

    在使用的时候,computed接收mapState函数的返回值,你可以用三种方式去接收store中的值,具体可以看注释

    事实上第二种和第三种是同一种,只是前者用了ES6的偷懒语法,箭头函数,在偷懒的时候要注意一个问题,this指针的指向问题,我已经在很多篇文章中提到不要在vue中为了偷懒使用箭头函数,会导致很多很难察觉的错误,如果你在用到state的同时还需要借助当前vue实例的this,请务必使用常规写法.

    当然computed不会因为引入mapState辅助函数而失去原有的功能---用于扩展当前vue的data,只是写法会有一些奇怪,如果你已经写了一大堆的computed计算属性,做了一半发现你要引入vuex,还想使用mapState辅助函数的方便,你可以需要做下列事情

    //之前的computed
    computed:{
        fn1(){ return ...},
        fn2(){ return ...},
        fn3(){ return ...}
        ........
    }
    //引入mapState辅助函数之后
     
    computed:mapState({
        //先复制粘贴
        fn1(){ return ...},
        fn2(){ return ...},
        fn3(){ return ...}
        ......
        //再维护vuex
        count:'count'
        .......
    })

    从上述写法可以看出来,这不符合代码的某些说不明道不清的特性,我们希望我们可以不用去做一些复制粘贴的无用操作,而是直接使用mapState,希望它能自动融入到当前生产环境中,ok,ES6+(或者说ES7)提供了这个方便

    3 ...mapState

    事实上...mapState并不是mapState的扩展,而是...对象展开符的扩展.当然如果你把他用在这里会发现他能使得代码看起来变得,更加符合常规逻辑了

    首先,来回顾一下...对象展开符在数组中的表现,这在ES6语法学习分类里有相关说明

    let arr = [1,2,3]
    console.log(...arr) //1,2,3

    然后来看一个例子

    let MapState = mapState({
          count: 'count',
          sex: (state) => state.sex
        })
        let json = {
          'a': '我是json自带的',
          ...MapState
        }
        console.log(json)

    这里的json可以成功将mapState return的json格式,和json自带的a属性成功融合成一个新的对象.你可以将这个称为对象混合

    这样,你就可以自由的使用mapState了

    //之前的computed
    computed:{
        fn1(){ return ...},
        fn2(){ return ...},
        fn3(){ return ...}
        ........
    }
    //引入mapState辅助函数之后
     
    computed:{
        //原来的继续保留
        fn1(){ return ...},
        fn2(){ return ...},
        fn3(){ return ...}
        ......
        //再维护vuex
        ...mapState({  //这里的...不是省略号了,是对象扩展符
            count:'count'
        })
    }
    computed: mapState([
        'count',
        'count2',
      ]),
    computed: {
          test: 'test sss',
          ...mapState(['count', 'count2']),
        },

    原文链接:https://blog.csdn.net/dkr380205984/article/details/82185740

  • 相关阅读:
    前端面试题(转载)
    郝兽医
    声明,本博客文章均为转载,只为学习,不为其他用途。感谢技术大牛的技术分享,让我少走弯路。
    ajax登陆+验证码(转载)
    新手机号
    明天回家
    ERP的灵魂-业务过程
    那些父母要求我们做的事
    出租车上的糗事
    管人管到心
  • 原文地址:https://www.cnblogs.com/yizhilin/p/13028336.html
Copyright © 2011-2022 走看看