Vuex實踐(下)-mapState和mapGetters

做者:小土豆biubiubiujavascript

博客園:www.cnblogs.com/HouJiao/html

掘金:https://juejin.im/user/58c61b4361ff4b005d9e894d前端

簡書:https://www.jianshu.com/u/cb1c3884e6d5vue

微信公衆號:土豆媽的碎碎念(掃碼關注,一塊兒吸貓,一塊兒聽故事,一塊兒學習前端技術)java

碼字不易,點贊鼓勵喲~es6

  

  Vuex系列文章web

    《Vuex實踐(上)》vuex

    Vuex實踐(中)-多module中的state、mutations、actions和getters數組

    《Vuex實踐(下)-mapState和mapGetters》瀏覽器

  

一.前言

  本文章是vuex系列的最後一篇,主要總結的是如何使用mapState和mapGetters訪問vuex中的state和getters。

二.多個模塊中mapState和mapGetters的使用

  上一篇文章《Vuex實踐(中)》裏面咱們總結的就是多模塊的內容,因此關於store.js、moduleA.js和moduleB.js的代碼保持不變。

  在此爲了方便觀看,我將這三個文件的代碼在貼在這裏

E:\MyStudy\test\VueDemo\src\vuex\store.js

 1 import Vue from 'vue'
 2 import Vuex from 'vuex'
 3 import moduleA from './moduleA'
 4 import moduleB from './moduleB'
 5 
 6 Vue.use(Vuex)  7 
 8 export default new Vuex.Store({  9  state: { 10         counter: 1000
11  }, 12  mutations: { 13         //遞增
14  increase(state) { 15             console.log("store-increase") 16             state.counter++
17  }, 18         //遞減
19  decrement(state) { 20             state.counter--
21  } 22  }, 23  actions: { 24  increaseAction(context) { 25             setTimeout(function(){ 26                 //action經過提交mutation改變共享數據狀態
27                 context.commit('increase'); 28             },3000) 29  }, 30  decrementAction(context){ 31             setTimeout(function(){ 32                 //action經過提交mutation改變共享數據狀態
33                 context.commit('decrement'); 34             },3000) 35  } 36  }, 37  getters: { 38  doubleCounter(state) { 39             return state.counter*state.counter 40  } 41  }, 42  modules: { 43  a: moduleA, 44  b: moduleB 45  } 46 })

 

E:\MyStudy\test\VueDemo\src\vuex\moduleA.js

const moduleA = { namespaced: true, state:{ counter: 100 }, mutations: { //遞增
 increase(state) { console.log("moduleA-increase") state.counter++ }, //遞減
 decrement(state) { state.counter-- } }, actions: { increaseAction(context) { setTimeout(function(){ //action經過提交mutation改變共享數據狀態
                context.commit('increase'); },3000) }, decrementAction(context){ setTimeout(function(){ //action經過提交mutation改變共享數據狀態
                context.commit('decrement'); },3000) } }, getters: { doubleCounter(state) { return state.counter*state.counter } } } export default moduleA

 

E:\MyStudy\test\VueDemo\src\vuex\moduleB.js

 1 const moduleB = {  2     namespaced: true,  3  state:{  4         counter: 5
 5  },  6  mutations: {  7         //遞增
 8  increase(state) {  9             console.log("moduleB-increase") 10             state.counter++
11  }, 12         //遞減
13  decrementAction(state) { 14             state.counter--
15  } 16  }, 17  actions: { 18  increaseAction(context) { 19             setTimeout(function(){ 20                 //action經過提交mutation改變共享數據狀態
21                 context.commit('increase'); 22             },3000) 23  }, 24  decrementAction(context){ 25             setTimeout(function(){ 26                 //action經過提交mutation改變共享數據狀態
27                 context.commit('decrement'); 28             },3000) 29  } 30  }, 31  getters: { 32  doubleCounter(state){ 33             return state.counter*state.counter 34  } 35  } 36 } 37 
38 export default moduleB

 

  如今須要在組件中使用mapState和mapGetters

  仍是按照以前的套路

  在App.vue組件中訪問根根模塊store和a模塊moduleA的state和getters。

  在Index.vue組件中訪問b模塊moduleB的state和getters

1.使用mapState

  使用mapState訪問state的寫法也有多種,咱們一個一個來實踐(不包含es6的寫法)

  [第一種寫法]

E:\MyStudy\test\VueDemo\src\App.vue  

<template>
  <div id="app">
    <img src="./assets/logo.png">
    <!-- 獲取共享數據 -->
    <h1>這裏是App組件</h1>
    <h3> App組件獲取共享數據 </h3>
    <h3>使用mapState訪問根組件counter : {{counter}}</h3>
    <h3>使用mapState訪問a組件counter : {{counterA}}</h3>
    <hr/>
    <Index></Index>
  </div>
</template>

<script> import Index from './components/Index' import { mapState } from 'vuex' export default { name: 'App', components: { Index }, computed: mapState({ //訪問store根模塊
 counter: function(state){ return state.counter }, //訪問a模塊
 counterA: function(state){ return state.a.counter } }) } </script>

<style> #app { font-family: 'Avenir', Helvetica, Arial, sans-serif; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; text-align: center; color: #2c3e50; margin-top: 60px;
}
</style>

 

E:\MyStudy\test\VueDemo\src\components\Index.vue

<template>
    <div>  
        <h1>這裏是Index.vue組件</h1>
        <h3>Index組件獲取共享數據 </h3>
        <h3>使用mapState訪問b模塊counter :{{ counterB }}</h3>
    </div>
</template>
<script> import { mapState } from 'vuex' export default { name: 'Index', computed: mapState({ counterB: function(state){ return state.b.counter } }) } </script>

 

  在App.vue、Index.vue組件中使用mapState,首先第一步須要引入mapState

  接着就是在計算屬性computed中使用,以Index.vue中的代碼爲例

computed: mapState({
    counterB: function(state){
         return state.b.counter
    }
})

     能夠看到mapState關聯到vue的計算屬性中。

  獲取b模塊的state,只須要以vue計算屬性的形式在函數中返回state.b.counter便可。

  (獲取根模塊state返回state.counter;獲取a模塊state返回state.a.counter)

  這樣在模板中就可使用計算屬性的語法訪問state

  備註:這種方式,當註釋掉命名空間的配置後,依然能夠正常訪問到不一樣模塊的state

  [第二種寫法]

  第二種寫法和第一種有些相似,只是以字符串的形式返回計算屬性。

  咱們先在Index.vue組件中訪問b模塊的數據。

E:\MyStudy\test\VueDemo\src\components\Index.vue

 1 <template>
 2     <div>  
 3         <h1>這裏是Index.vue組件</h1>
 4         <h3>Index組件獲取共享數據 </h3>
 5         <h3>使用mapState訪問b模塊counter :{{ counterB }}</h3>
 6     </div>
 7 </template>
 8 <script>
 9 import { mapState } from 'vuex'
10 export default { 11  name: 'Index', 12  computed: mapState('b',{ 13  counterB: 'counter'
14  }) 15 } 16 </script>

  核心代碼以下

computed: mapState('b',{
    counterB: 'counter'
})

    能夠看到,mapState第一個參數限定了模塊名稱。

  接着就是以'counter'字符串的形式返回了b模塊的counter值。

  那麼根據以前一系列的總結,可知

    訪問根模塊的數據,不須要限定第一個參數;

    訪問a模塊的數據,須要限定第一個參數爲a

  然而,由於訪問根模塊和訪問a模塊同在App.vue組件中,那麼由於mapState第一個參數限定的問題,咱們須要編寫兩個mapState。

  如今直接上代碼(只把computed中的核心代碼貼上)

E:\MyStudy\test\VueDemo\src\App.vue  

computed: { ...mapState({ //訪問store根模塊
      counter: 'counter', }), ...mapState('a',{ //訪問a模塊
      counterA: 'counter' }) }

  能夠看到,我寫了兩個mapState,仍是...mapState的形式。

  ...mapState它是ES6中擴展運算符的語法,應用在mapState上,官方文檔是這樣說的

  

   (

    此處若對此有疑問,能夠在去仔細研究一下對象擴展運算符的內容。

    我這裏貼一個簡單的示例

    

      最終newObj的打印結果爲  

    相信這個示例能夠很清楚的解釋咱們寫的兩個...mapState的寫法

  )

  官方文檔處提到這個對象展開運算符的場景是爲了將一個組件中本來的計算屬性和mapState混合使用

  (混合使用這個點平常開發會用到,很實用的一個點)

  那本次咱們也是使用這個語法成功的獲取到了不一樣模塊的state。

 

  最後咱們在使用瀏覽器查看一下最終App.vue和Index.vue中的結果

  

  咱們已經使用mapState成功的訪問到了多模塊中的state數據。

 

  備註:這種關於mapState的寫法不能刪除moduleA和moduleB中關於命令空間的配置,不然會報錯。

  最後做者還嘗試了一個問題,就是將moduleA.js中的state屬性改成counterA

  

  而後修改了App.vue組件中computed訪問a模塊數據的代碼

  

  最後發現這樣並不能正常訪問到a模塊的state數據。(刪除a模塊的命名空間配置也沒法正常訪問)

  這個嘗試僅給你們一個反面的示例。

2.使用mapGetters

  前面使用mapState訪問了state數據,那麼如今咱們使用mapGetters訪問一下vuex中的getters。

  在研究以後發現,暫時發現使用mapGetters訪問一下vuex中的getters只有字符串的形式。

E:\MyStudy\test\VueDemo\src\App.vue

 1 <template>
 2   <div id="app">
 3     <img src="./assets/logo.png">
 4     <!-- 獲取共享數據 -->
 5     <h1>這裏是App組件</h1>
 6     <h3> App組件獲取共享數據 </h3>
 7     <h3>使用mapState訪問根組件counter : {{counter}}</h3>
 8     <h3>使用mapState訪問a組件counter : {{counterA}}</h3>
 9     <h3>使用mapGetters訪問根組件doubleCounter : {{doubleCounter}}</h3>
10     <h3>使用mapGetters訪問a組件doubleCounter : {{doubleCounterA}}</h3>
11     <hr/>
12     <Index></Index>
13   </div>
14 </template>
15 
16 <script>
17 import Index from './components/Index'
18 import { mapState,mapGetters } from 'vuex'
19 export default { 20  name: 'App', 21  components: { Index }, 22  computed: { 23  ...mapState({ 24       //訪問store根模塊
25  counter: 'counter', 26  }), 27  ...mapState('a',{ 28       //訪問a模塊
29  counterA: 'counter'
30  }), 31  ...mapGetters({ 32       //訪問store根模塊
33  doubleCounter: 'doubleCounter'
34  }), 35  ...mapGetters('a',{ 36       //訪問store根模塊
37  doubleCounterA: 'doubleCounter'
38  }) 39 
40  } 41   
42 } 43 </script>
44 
45 <style>
46 #app {
47  font-family: 'Avenir', Helvetica, Arial, sans-serif;
48  -webkit-font-smoothing: antialiased;
49  -moz-osx-font-smoothing: grayscale;
50  text-align: center;
51  color: #2c3e50;
52  margin-top: 60px;
53 }
54 </style>

 

E:\MyStudy\test\VueDemo\src\components\Index.vue

 1 <template>
 2     <div>  
 3         <h1>這裏是Index.vue組件</h1>
 4         <h3>Index組件獲取共享數據 </h3>
 5         <h3>使用mapState訪問b模塊counter :{{ counterB }}</h3>
 6         <h3>使用mapGetters訪問b組件doubleCounter : {{doubleCounterB}}</h3>
 7     </div>
 8 </template>
 9 <script>
10 import { mapState,mapGetters } from 'vuex'
11 export default { 12  name: 'Index', 13  computed: { 14  ...mapState('b',{ 15  counterB: 'counter'
16  }), 17  ...mapGetters('b',{ 18  doubleCounterB: 'doubleCounter'
19  }), 20  } 21 } 22 </script>

 

  瀏覽器查看結果

  

三.總結

  到此本篇文章基本已經結束了,vuex系列的三篇文章也已經結束。

  關於vuex中大多數的用法基本已經覆蓋到,可是還有一些內容沒有覆蓋到。

  後期攢夠一篇在繼續更新

  在最後呢,再補充一點,無論是mapState和mapGetters,咱們給傳入的都是一個字典。

  簡單一些的,假如咱們的state和getters不重名,咱們能夠給mapState和mapGetters傳入一個數組

1 mapState([ 2      'counterA','counterB',... 3 ]) 4 
5 mapGetters([ 6      'dobuleCounterA','dobuleCounterB',... 7 ])

  這樣數組中的字符串元素會直接去映射對應的state和getters。

  (字典形式至關因而將state和getters中的名稱在映射過程當中進行重命名)


  

原文出處:https://www.cnblogs.com/HouJiao/p/12186237.html

相關文章
相關標籤/搜索