Vuex 注入 Vue 生命週期的過程

2022-06-05 17:51:09 字數 3730 閱讀 5936

首先我們結合 vue 和 vuex 的部分原始碼,來說明 vuex 注入 vue 生命週期的過程。

說到原始碼,其實沒有想象的那麼難。也和我們平時寫業務**差不多,都是方法的呼叫。但是原始碼的呼叫樹會複雜很多。

使用 vue 我們就不可避免的會遇到元件間共享的資料或狀態。應用的業務**逐漸複雜,props、事件、事件匯流排等通訊的方式的弊端就會愈發明顯。這個時候我們就需要 vuex 。vuex 是乙個專門為 vue 設計的狀態管理工具。

狀態管理是 vue 元件解耦的重要手段。

它借鑑了 flux、redux 的基本思想,將狀態抽離到全域性,形成乙個 store。

vuex 不限制你的**結構,但需要遵守一些規則:

應用層級的狀態應該集中到單個 store 物件中

提交 mutation 是更改狀態的唯一方法,並且這個過程是同步的

非同步邏輯都應該封裝到 action 裡面

我們在安裝外掛程式的時候,總會像下面一樣用vue.use()來載入外掛程式,可是vue.use()做了什麼呢?

importvuefrom'vue';importvuexfrom'vuex';vue.use(vuex);

安裝 vue.js 外掛程式。如果外掛程式是乙個物件,必須提供 install 方法。如果外掛程式是乙個函式,它會被作為 install 方法。install 方法呼叫時,會將 vue 作為引數傳入。

以上是 官方文件 的解釋。

接下來我們從原始碼部分來看看vue.use()都做了什麼。

vue 原始碼在initglobalapi入口方法中呼叫了inituse (vue)方法,這個方法定義了vue.use()需要做的內容。

這段**主要做了兩件事情:

一件是防止重複安裝相同的 plugin

另一件是初始化 plugin

看完以上原始碼,我們知道外掛程式(vuex)需要提供乙個install方法。那麼我們看看 vuex 原始碼中是否有這個方法。結果當然是有的:

這段**主要做了兩件事情:

一件是防止 vuex 被重複安裝

從上面的原始碼,可以看出vue.mixin方法將vuexinit方法混淆進beforecreate鉤子中,也是因為這個操作,所以每乙個 vm 例項都會呼叫vuexinit方法。那麼vuexinit又做了什麼呢?

我們在使用 vuex 的時候,需要將 store 傳入到 vue 例項中去。

});但是我們卻在每乙個 vm 中都可以訪問該 store,這個就需要靠vuexinit了。

functionvuexinit ()elseif(options.parent &&options.parent.$store)}

根節點存在 stroe 時,則直接將options.store賦值給this.$store。否則則說明不是根節點,從父節點的$store中獲取。

通過這步的操作,我們就以在任意乙個 vm 中通過 this.$store 來訪問 store 的例項。接下來我們反過來說說 vue.mixin()。

全域性註冊乙個混入,影響註冊之後所有建立的每個 vue 例項。外掛程式作者可以使用混入,向元件注入自定義的行為。不推薦在應用**中使用。

在 vue 的initglobalapi入口方法中呼叫了initmixin$1(vue)方法:

functioninitmixin$1 (vue);}

vuex 注入 vue 生命週期的過程大概就是這樣,如果你感興趣的話,你可以直接看看 vuex 的原始碼,接下來我們說說 store。

上面我們講到了vuexinit會從 options 中獲取 store。所以接下來會講到 store 是怎麼來的呢?

我們使用 vuex 的時候都會定義乙個和下面類似的 store 例項。

importvuefrom'vue'importvuexfrom'vuex'importmutations from'./mutations'vue.use(vuex)conststate =exportdefaultnewvuex.store()

不要在發布環境下啟用嚴格模式。嚴格模式會深度監測狀態樹來檢測不合規的狀態變更 —— 請確保在發布環境下關閉嚴格模式,以避免效能損失。

你是否關心 state 是如何能夠響應式呢?這個主要是通過 store 的建構函式中呼叫的resetstorevm(this, state)方法來實現的。

這個方法主要是重置乙個私有的 _vm(乙個 vue 的例項) 物件。這個 _vm 物件會保留我們的 state 樹,以及用計算屬性的方式儲存了 store 的 getters。現在具體看看它的實現過程。

/* 使用 vue 內部的響應式註冊 state */functionresetstorevm (store,state,hot),computed

})vue.config.silent =silent

/* 使能嚴格模式,vuex 中對 state 的修改只能在 mutation 的**函式裡 */if(store.strict)if(oldvm))}vue.nexttick(()=>oldvm.$destroy())}}

state 的響應式大概就是這樣實現的,也就是初始化 resetstorevm 方法的過程。

我們知道 commit 方法是用來觸發 mutation 的。

commit (_type,_payload,_options)=unifyobjectstyle(_type,_payload,_options)constmutation =/* 找到相應的 mutation 方法 */constentry =this._mutations[type]if(!entry)`)}return}/* 執行 mutation 中的方法 */this._withcommit(()=>)})/* 通知所有訂閱者,傳入當前的 mutation 物件和當前的 state */this._subscribers.foreach(sub=>sub(mutation,this.state))if(process.env.node_env !=='production'&&options &&options.silent

). silent option has been removed. `+'use the filter functionality in the vue-devtools')}}

該方法先進行引數風格校驗,然後利用_withcommit方法執行本次批量觸發mutation處理函式。執行完成後,通知所有_subscribers(訂閱函式)本次操作的mutation物件以及當前的state狀態。

vue生命週期

beforecreate 元件例項剛剛被建立,屬性都沒有 create 例項已經建立完成,屬性已經繫結 beforemount 模板編譯之前 mounted 模板編譯之後 beforeupdate 元件更新之前 updated 元件更新完畢 beforedestroy 元件銷毀之前 destroye...

vue生命週期

vue把整個生命週期劃分為建立 掛載 更新 銷毀等階段,每個階段都會給一些 鉤子 讓我們來做一些我們想實現的動作。學習例項的生命週期,能幫助我們理解vue例項的運作機制,更好地合理利用各個鉤子來完成我們的業務 我們分別來看看這幾個階段 1.beforecreate 此階段為例項初始化之後,此時的資料...

Vue 生命週期

import vue from vue el root 沒有的話,使用render,繼續沒有,就把el的outerhtml編譯成模板 template temp data beforecreate created el是原來的el beforemount 渲染函式 render h this.tex...