[手把手式教程,適合新手入門Vuex]-Vuex入門實踐(下)

做者:小土豆biubiubiujavascript

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

掘金:juejin.im/user/58c61b…html

簡書:www.jianshu.com/u/cb1c3884e…前端

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

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

前言

本文章是Vuex系列的最後一篇,主要總結的是如何使用mapStatemapGetters訪問Vuex中的stategettersweb

準備階段

上一篇文章 [手把手式教程,適合新手入門Vuex]-Vuex入門實踐(中) 裏面咱們總結的是多模塊的內容,因此關於store.jsmoduleA.jsmoduleB.js的代碼保持不變。vuex

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

// E:\MyStudy\test\VueDemo\src\vuex\store.js
import Vue from 'vue'
import Vuex from 'vuex'
import moduleA from './moduleA'
import moduleB from './moduleB'

Vue.use(Vuex)

export default new Vuex.Store({
    state: {
        counter: 1000
    },
    mutations: {
        //遞增
        increase(state) {
            console.log("store-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
        }
    },
    modules: {
        a: moduleA,
        b: moduleB
    }
})
複製代碼
// 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
const moduleB = {
    namespaced: true,
    state:{
        counter: 5
    },
    mutations: {
        //遞增
        increase(state) {
            console.log("moduleB-increase")
            state.counter++
        },
        //遞減
        decrementAction(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 moduleB
複製代碼

注意這裏不能缺乏命令空間的配置哦瀏覽器

如今須要在組件中使用mapStatemapGettersstategetters進行訪問,仍是按照以前的套路:

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

在Index.vue組件中訪問b模塊的state和getters
複製代碼

使用mapState

使用mapState訪問state的寫法也有多種,咱們一個一個來實踐。

第一種寫法

咱們先直接上代碼。

<!-- E:\MyStudy\test\VueDemo\src\App.vue&emsp;-->
<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>
複製代碼

在組件中使用mapState,首先第一步須要引入mapState

import { mapState } from 'vuex'
複製代碼

接着就是在組件的計算屬性computed使用mapState,以Index組件中的代碼爲例。

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

第二種寫法

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

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

<!-- 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('b',{ counterB: 'counter' }) } </script>
複製代碼

核心代碼以下:

computed: mapState('b',{
    counterB: 'counter'
})
複製代碼

能夠看到,這種寫法mapState第一個參數限定了模塊名稱。接着就是以counter字符串的形式返回了b模塊的counter值。那麼咱們就能夠知道訪問store跟模塊、a模塊的方法以下:

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

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

接着就有個問題了:訪問store根模塊、a模塊的state代碼同在App.vue組件中,那麼由於mapState第一個參數限定的問題,咱們須要編寫兩個mapState

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

// E:\MyStudy\test\VueDemo\src\App.vue&emsp;
computed: {
    ...mapState({
      //訪問store根模塊
      counter: 'counter',
    }),
    ...mapState('a',{
      //訪問a模塊
      counterA: 'counter'
    })
}
複製代碼

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

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

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

我這裏貼一個簡單的示例

最終 newObj的打印結果爲  

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

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

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

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

注意:

這種關於mapState的寫法不能刪除moduleAmoduleB中關於命令空間的配置,不然會報錯。

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

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

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

這個嘗試僅給你們一個反面的示例,具體爲何不能訪問應該須要去閱讀Vuex的源碼才能知曉,所以這裏不在探究。

使用mapGetters

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

在嘗試以後發現,暫時發現使用mapGetters訪問Vuex中的getters只有字符串的形式

<!-- 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>
    <h3>使用mapGetters訪問根組件doubleCounter : {{doubleCounter}}</h3>
    <h3>使用mapGetters訪問a組件doubleCounter : {{doubleCounterA}}</h3>
    <hr/>
    <Index></Index>
  </div>
</template>

<script> import Index from './components/Index' import { mapState,mapGetters } from 'vuex' export default { name: 'App', components: { Index }, computed: { ...mapState({ //訪問store根模塊 counter: 'counter', }), ...mapState('a',{ //訪問a模塊 counterA: 'counter' }), ...mapGetters({ //訪問store根模塊 doubleCounter: 'doubleCounter' }), ...mapGetters('a',{ //訪問store根模塊 doubleCounterA: 'doubleCounter' }) } } </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>
        <h3>使用mapGetters訪問b組件doubleCounter : {{doubleCounterB}}</h3>
    </div>
</template>
<script> import { mapState,mapGetters } from 'vuex' export default { name: 'Index', computed: { ...mapState('b',{ counterB: 'counter' }), ...mapGetters('b',{ doubleCounterB: 'doubleCounter' }), } } </script>

複製代碼

App組件中關於mapGetters的核心代碼以下:

computed: {
    ...mapGetters({
      //訪問store根模塊
      doubleCounter: 'doubleCounter'
    }),
    ...mapGetters('a',{
      //訪問store根模塊
      doubleCounterA: 'doubleCounter'
    })

  }
複製代碼

Index組件中關於mapGetters的核心代碼以下:

computed: {
    ...mapGetters('b',{
        doubleCounterB: 'doubleCounter'
    }),
}
複製代碼

瀏覽器查看結果:

總結

到此本篇文章基本已經結束了。

在最後呢,再補充一點,不論是mapStatemapGetters,咱們給傳入的都是一個字典。

...mapState({
  counter: 'counter',
}),
...mapGetters({
  doubleCounter: 'doubleCounter'
}),
複製代碼

簡單一些的,假如咱們的stategetters不重名,咱們能夠給mapStatemapGetters傳入一個數組。

mapState([
     'counterA','counterB',...
])

mapGetters([
     'dobuleCounterA','dobuleCounterB',...
])
複製代碼

這樣數組中的字符串元素會直接去映射對應的stategetters

字典形式至關因而將stategetters中的名稱在映射過程當中進行重命名

Vuex入門實踐系列文章總結

到此[手把手式教程,適合新手入門Vuex]-Vuex入門實踐 這整個系列就結束了,都是一些關於Vuex基礎的用法,比較適合新手剛開始學習和實踐Vuex

最後呢,將這個系列的全部文章連接整理到這裏,方便你們觀看。

[手把手式教程,適合新手入門Vuex]-Vuex入門實踐(上)

[手把手式教程,適合新手入門Vuex]-Vuex入門實踐(中)

[手把手式教程,適合新手入門Vuex]-Vuex入門實踐(下)

關於

做者

小土豆biubiubiu

一個努力學習的前端小菜鳥,知識是無限的。堅信只要不停下學習的腳步,總能到達本身指望的地方

同時仍是一個喜歡小貓咪的人,家裏有一隻美短小母貓,名叫土豆

博客園

www.cnblogs.com/HouJiao/

掘金

juejin.im/user/58c61b…

簡書

www.jianshu.com/u/cb1c3884e…

微信公衆號

土豆媽的碎碎念

微信公衆號的初衷是記錄本身和身邊的一些故事,同時會不按期更新一些技術文章

歡迎你們掃碼關注,一塊兒吸貓,一塊兒聽故事,一塊兒學習前端技術

羣聊

歡迎你們掃描微信二維碼進入羣聊討論問題(若二維碼失效可添加微信JEmbrace拉你進羣)

做者寄語

小小總結,歡迎你們指導~

相關文章
相關標籤/搜索