詳解如何?一個簡單的 vuex,詳解實現vuex

來源:互聯網
上載者:User

詳解如何?一個簡單的 vuex,詳解實現vuex

首先我們需要知道為何要使用 vuex。父子組件通訊用 prop 和自訂事件可以搞定,簡單的非父子組件通訊用 bus(一個空的 Vue 執行個體)。那麼使用 vuex 就是為瞭解決複雜的非父子組件通訊。

僅僅會使用 vuex 沒什麼,看過文檔敲敲代碼大家都會。難道你就不想知道 vuex 是如何?的?!

拋開 vuex 的源碼,我們先來想想如何?一個簡單的 "vuex"。有多簡單呢,我不要 getter、mutation、action 等,我只要 state 就行了。

非父子組件通訊

在實現之前,我們得來溫故一下 bus 的實現,借用官網的例子:

var bus = new Vue()// 觸發組件 A 中的事件bus.$emit('id-selected', 1)// 在組件 B 建立的鉤子中監聽事件bus.$on('id-selected', function (id) { // ...})

遙想當年,執行個體化後的 bus 不知放哪好,最後無奈將其放到了 window 下,一直 window.bus 的使用。雖然這樣也沒問題,但還是影響到了全域範圍。

突然的某一天,我發現可以掛載在 vue 的根執行個體下(從此告別 window.bus),於是便有了:

var app = new Vue({ el: '#app', bus: bus})// 使用 busapp.$options.bus// orthis.$root.$options.bus

然後又發現了,bus 其實不只是 on 事件才可以通訊。其實 bus 是一個 Vue 執行個體,其中 data 是響應的。比如在 app 這個根執行個體下有兩個非父子組件,都使用到了 bus 的 data,那麼它們是響應同步的。

var bus = new Vue({ data: {  count: 0 }})

以上,子組件 a 修改了 count,如果子組件 b 有用到 count,那麼它就能響應到最新 count 的值。

說了這麼多,你還沒發現嗎?這個不就是實現了非組件之間通訊,vuex 的 state 嗎?!

封裝 bus

是的,把剛剛的 bus 封裝一下,這個就是一個最簡單的 "vuex" (僅僅只有 state 的功能)。首先,我們將有一個根執行個體 app ,執行個體下有兩個非父子組件 childA 和 childB 。

html 代碼的實現如下:

<div id="app"> <child-a></child-a> <child-b></child-b></div>

非父子組件的實現

然後是兩個非父子組件和 app 的實現,子組件都使用到了 bus 的 count,這裡用 store.state 表示,跟 vuex 一致:

// 待實現const store = new Store(Vue, { state: {  count: 0 }})// 子組件 aconst childA = { template: '<button @click="handleClick">click me</button>', methods: {  handleClick () {   this.$store.state.count += 1  } }}// 子組件 bconst childB = { template: '<div>count: {{ count }}</div>', computed: {  count () {   return this.$store.state.count  } }}new Vue({ el: '#app', components: {  'child-a': childA,  'child-b': childB }, store: store})

看到代碼裡還有一個 Store 待實現。所需要的參數,因為這裡懶得用 Vue.use() ,所以直接將 Vue 作為參數傳入以供使用,然後第二個參數跟我們使用 vuex 傳入的參數一致。

Store 的實現

接下來就是 Store 的實現,兩步實現:

  1. 建立一個 bus 執行個體;
  2. 讓子組件都能訪問到 this.$store。

第 1 步驟上面已經有了,第 2 步驟主要用到了 Vue.mixin 來全域混入,但僅僅只是找到有 store 的根執行個體並賦值 Vue 原型上的 store,也能夠讓根執行個體 app 不用專門寫 mixins 混入。

class Store { constructor (Vue, options) {  var bus = new Vue({   data: {    state: options.state   }  })  this.install(Vue, bus) }  install (Vue, bus) {  Vue.mixin({   beforeCreate () {    if (this.$options.store) {     Vue.prototype.$store = bus    }   }  }) }}

實現的 Store 就是一個簡單的 "vuex",它擁有了 vuex 的 state,足夠讓非父子組件之間進行簡單通訊。

在 Store 的建構函式裡建立一個 bus 執行個體,並將其注入 Vue 的原型,實現了組件都能訪問到 this.$store 即 bus 執行個體。 this.$store 就是一個 Vue 執行個體,所以訪問了 this.$store.state.count 實際上就是訪問到了 data,從而實現了非父子組件之間的響應同步。全部源碼參考這裡 。

以上就是本文的全部內容,希望對大家的學習有所協助,也希望大家多多支援幫客之家。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.