Vue 教程第十二篇—— Vuex 介紹和簡單實現

圖片描述# Vuex
在介紹 Vuex 以前,我先拋出一個問題,以下圖javascript

圖片描述

請原諒並忽略手繪圖的粗糙,主要描述的結構是:html

  • 組件Avue

    • 組件Bjava

      • 組件B1git

        • 事件:Event1
        • 事件:Event2
        • 事件:Event3
      • 組件B2github

        • 事件:Event1
        • 事件:Event2
        • 事件:Event3
    • 組件Cvuex

      • 組件C1app

        • 事件:Event1
        • 事件:Event2
        • 事件:Event3
      • 組件C2this

        • 事件:Event1
        • 事件:Event2
        • 事件:Event3

如今的問題要解決是組件C1或者C2要和組件B1或B2通訊,前面有詳細講過 Vue 自己組件之間通訊的方法,最簡單的就是 $parent$children,若是不知道如何使用的請回到上面看 組件通訊spa

如今用 $parent$children 來上面的問題:組件C1調用組件B2的方法

this.$parent.$parent.$children[0].$children[1].Event1()

代碼寫到這問題解決了,可是若是再多幾層的組件嵌套關係,又或者組件層級關係因需求發生了改變,那上面的代碼又得從新改變。

爲了解決這樣的問題,有人想到了把爲什麼不把全部組件的方法統一到一個公共對象,由於對象是一個無序屬性集合,並且仍是引用類型,而後把這個對象放到最外層,這樣無論組件嵌套多少級,都能調用到對應的方法。

那上面的案例就能夠生成以下面這種結構的對象了

var obj = {
        A: {},
        B: {},
        B1: {
            Event1: function(){},
            Event2: function(){},
            Event3: function(){}
        },
        B2: {
            Event1: function(){},
            Event2: function(){},
            Event3: function(){}
        },        
        C: {},
        C1: {
            Event1: function(){},
            Event2: function(){},
            Event3: function(){}
        },
        C2: {
            Event1: function(){},
            Event2: function(){},
            Event3: function(){}
        },         
    }

跨組件通訊之——公共對象

場景:在組件 home 裏面使用組件 counter,在 home 組件中實現計數,在組件 counter 同步顯示當前計數。

common.js

export default {
    state: {
        count: 0
    }
}

countercomponent

<template>
    <div>
        <h3>count-{{common.state.count}}</h3>
    </div>
</template>

<script>
    import common from '../../common/common.js'
    export default {
        data(){
            return {
                common
            }
        }
    }
</script>

homecomponent

<template>
    <div>
        <fieldset>
            <legend><h3>home</h3></legend>
            <div>
                <input type="button" value="increment" @click="increment"/>
                <span>{{common.state.count}}</span>
            </div>
        </fieldset>
        <fieldset>
            <legend><h3>counter</h3></legend>
            <counter></counter>
        </fieldset>
        
    </div>
</template>

<script>
    import common from '../../common/common.js'
    import counter from '../counter/counter.vue'

    export default {
        data(){
            return {
                common
            }
        },
        components: {
            datagrid,
            counter
        },
        methods: {
            increment(){
                this.common.state.count += 1;
            }
        }
    }
</script>

上面的案例是經過公共對象解決了簡單的跨組件通訊的問題,但若是組件 counter 也想能能夠實現計數,那最簡單的實現方法就是在組件 counter 當中也寫一個事件 increment,但這樣一來,事件就重複了。

封裝實現就是把事件 increment 也放到 common.js 對象中去,而後組件都調用這個公共的方法。

let state = {
    count: 0
}

let mutations = {
    increment(){
        state.count += 1;
    }
}
export default {
    state,
    mutations
};

看似解決了問題,可是若是場景更復雜,組件層級更深,組件間要通訊的信息更多,組件間存在同名屬性同名方法但不一樣邏輯等,目前這種方法就解決不了,須要進行更深層次的封裝。

Vuex 就是上面這種解決方案的更深層次的實現。

跨組件通訊之——Vuex

store.js

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

let state = {
    count: 0
}

let mutations = {
    increment(){
        state.count += 1;
    },
    decrement(){
        state.count -= 1;
    }
}

const store = new Vuex.Store({
    state,
    mutations
})

export default store

app.js

import Vue from 'vue'
import store from './vuex/store'

import homeComponent from './components/home/home.vue'

new Vue({
    el: '#app',
    store,
    render:h => h(homeComponent)
})

homecomponent

<input type="button" value="increment" @click="increment"/>
<span>{{$store.state.count}}</span>
<script type="text/javascript">
    methods: {
        increment(){
            this.$store.commit('increment');
        }
    }    
</script>

countercomponent

<span>{{$store.state.count}}</span>

小結

  • Vuex 實例 store,添加到 Vue 實例化當中去,而後整個 Vue 實例都能經過 $store 獲取到公共對象 store。
  • this.$store.commit('increment'); 觸發 mutations 的 increment 方法
  • state 是經過 mutations 來改變
  • $store.state.count獲取 store 的 state。
相關文章
相關標籤/搜索