1. 程式人生 > >Vuex入門(3)—— getters,mapGetters,...mapGetters詳解

Vuex入門(3)—— getters,mapGetters,...mapGetters詳解

  Vuex提供了state這樣的狀態統一管理樹,你可以在vue中用computed計算屬性接收這些公共狀態,以便使用,當然你也可以在接收原值的基礎上對這個值做出一些改造,如

computed:{
  sex:function(){
      return this.$store.state.sex + '加個字串,算是改造'    
  }
}

  但是如果你的其他元件也要使用這種改造方式去改造這個值,那你可能不得不去複製貼上這個函式到別的元件中,當然,為了解決這個問題,vuex本身就提供了類似於計算屬性的方式,getters可以讓你從store的state中派生出一些新的狀態,當然如果不是多個元件要用到這個狀態,或者說每個子元件用到的派生屬性不一樣,那麼,你完全可以不用getters.(這裡多說一句吧,vuex的出現是為了解決元件間的通訊問題,如果你的操作或者資料不涉及到公共操作,只是單一元件操作,請務必不要把這些狀態值或者function儲存到vuex中,因為vuex會把自身掛載到所有元件上,不管當前元件是否用到裡面的東西,因此這事實上肯定增加了效能的損耗,注意是肯定,因為你很難保證每個子元件都用到同一個狀態,除非是路由這樣的特殊狀態,當然路由的事情也無需歸vuex管理,在後面vue-router系列中會講到.

)

1.getters

  Vuex 允許我們在 store 中定義“getter”(可以認為是 store 的計算屬性)。就像計算屬性一樣,getter 的返回值會根據它的依賴被快取起來,且只有當它的依賴值發生了改變才會被重新計算。說白了就是vue的computed,如果你瞭解computed的話,那你可以像使用computed一樣去使用getters,當然還是有點區別的.

//state.js
let state = {
  from: 'china',
  arr: [2, 3, 1, 4, 6]
}
export default state
// getters.js
// 第一個引數是state
let address = (state) => {
  return '國籍:' + state.from
}
// 第二個引數可以訪問getters
let addressMore = (state, getters) => {
  return '其他描述' + getters.address
}
// return 一個function,這個function可以傳參,當然這個function最後會返回一個具體的數值
//本例中這個方法用於查詢state中的arr陣列是否存在某個值
let findArr = (state) => (number) => {
  let ifExit = state.arr.find((n) => n === number) // arr.find是ES6語法中陣列的擴充套件
  if (typeof (ifExit) === 'undefined') {
    return false
  } else {
    return true
  }
}
export {address, addressMore, findArr}

  關於getters如何使用,可以看一下上面程式碼的註釋,這裡我重點介紹一下getters和computed的不同,就是上面的第三種用法,我之前在vue進階系列中探討過computed,filters兩種資料處理工具的侷限性,有興趣的可以去看這篇文章,computed的一個缺點就是不能傳參,假設你要去判斷一個數組裡是否存在某個值,那你沒法將某個值傳到computed中去,這其實是一個很蛋疼的事情,當然你可以通過某些特殊手段,這裡我不展開,有興趣的可以留言.而getters則沒有這個煩惱,有些對ES6語法使用較為吃力的同學可以看下面的簡易版本,來看看findArr究竟做了什麼.

let findArr = function(state){
  // 返回一個匿名函式
  return function(number){
    // 如果有相同的則返回n,如果找不到則返回undefined
    let ifExit = state.arr.find(function(n){
      return n===number
    })
    if (typeof (ifExit) === 'undefined') {
      return false
    } else {
      return true
    }
  }
}

  最後我們在子元件中展示一下效果

<template>
  <div>
    <div>{{from}}</div>
    <div>{{from2}}</div>
  </div>
</template>

<script>
// import { mapGetters } from 'vuex'
export default {
  computed: {
    from: function () {
      return this.$store.getters.address
    },
    from2: function () {
      return this.$store.getters.addressMore
    }
  },
  created () {
    console.log(this.$store.getters.findArr(2))
    console.log(this.$store.getters.findArr(7))
  }
}
</script>

結果如下所示.

 2.mapGetters 輔助函式

  關於輔助函式的使用和物件展開符的使用我在本系列的第二章中已經說的很明白了,有興趣的可以看一下這個連結

<template>
  <div>
    <div>{{from}}</div>
    <div>{{from2}}</div>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
export default {
  computed:  mapGetters({
      'from': 'address',
      'from2': 'addressMore',
      'find': 'findArr'
  }),
  created () {
    console.log(this.find(1)) // 由於getters已經通過computed掛載到當前例項,所以你不需要再通過this.$store.getters的方法去訪問
    console.log(this.$store.getters.findArr(2))
    console.log(this.$store.getters.findArr(7))
  }
}
</script>

 3....mapGetters

<template>
  <div>
    <div>{{from}}</div>
    <div>{{from2}}</div>
  </div>
</template>

<script>
import { mapGetters } from 'vuex'
export default {
  computed:  {
    ...mapGetters({
      'from': 'address',
      'from2': 'addressMore',
      'find': 'findArr'
    })
  },
  created () {
    console.log(this.find(1)) // 由於getters已經通過computed掛載到當前例項,所以你不需要再通過this.$store.getters的方法去訪問
    console.log(this.$store.getters.findArr(2))
    console.log(this.$store.getters.findArr(7))
  }
}
</script>

  最後在說一句,很多情況下你是用不到getters的,請按需使用,不要用getters去管理state的所有派生狀態,如果有多個子元件或者說子頁面要用到,才考慮用getters.