Vuex入门(2)—— state,mapState,...mapState对象展开符详解

在CSDN上本章节内容有3W+的阅读量,是这个系列最受欢迎的章节,从某种角度上讲,本文对mapstate的讲解甚至要好于官网(这是我经过别人的评价得知的),目前该文章在百度上的搜索权重已经超过了官网。事实上,我本人并无以为这篇文章有多出彩,跟真正的大佬比起来,差距也不是一点半点,闲话很少说,下面开始一本正经的博客搬家。javascript

1.state

state是什么? html

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

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

虽然state和data有不少类似之处,但state在使用的时候通常被挂载到子组件的computed计算属性上,这样有利于state的值发生改变的时候及时响应给子组件.若是你用data去接收$store.state,固然能够接收到值,但因为这只是一个简单的赋值操做,所以state中的状态改变的时候不能被vue中的data监听到,固然你也能够经过watch $store去解决这个问题,那你能够针是一个杠精。(我从新看了下这段话的逻辑,逻辑自己没有问题,但对初学者来讲可能不是很是友好,能够跳过) vuex

综上所述,请用computed去接收state,以下: json

//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是什么? bash

表面意思:mapState是state的辅助函数.这么说可能很难理解 dom

抽象形容: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'
    })
}
复制代码

本章的内容到这儿就结束了,下一章是关于getters,mapGetters,...mapGetters详解部分,对这个系列感兴趣的给个赞吧~

不忘初心,方得始终

喜欢博主的童鞋能够扫描二维码加博主好友~ 也能够扫中间二维码入驻博主的粉丝群(708637831)~固然你也能够扫描二维码打赏并直接包养帅气的博主一枚。

相关文章
相关标签/搜索