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)~固然你也能夠掃描二維碼打賞並直接包養帥氣的博主一枚。

相關文章
相關標籤/搜索