[轉] Vuex入門(2)—— state,mapState,...mapState對象展開符詳解


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是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語法學習分類里有相關說明,如果有興趣可以關注我的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'
})
}
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM