欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談Vuex注入Vue生命周期的過程

 更新時間:2019年05月20日 10:49:28   作者:小生方勤  
這篇文章主要介紹了Vuex 注入 Vue 生命周期的過程,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

這篇文章是【前端詞典】系列文章的第 13 篇文章,接下的 9 篇我會圍繞著 Vue 展開,希望這 9 篇文章可以使大家加深對 Vue 的了解。當然這些文章的前提是默認你對 Vue 有一定的基礎。如果一點基礎都沒有,建議先看官方文檔。

第一篇文章我會結(jié)合 Vue 和 Vuex 的部分源碼,來說明 Vuex 注入 Vue 生命周期的過程。

說到源碼,其實沒有想象的那么難。也和我們平時寫業(yè)務代碼差不多,都是方法的調(diào)用。但是源碼的調(diào)用樹會復雜很多。

為何使用 Vuex

使用 Vue 我們就不可避免的會遇到組件間共享的數(shù)據(jù)或狀態(tài)。應用的業(yè)務代碼逐漸復雜,props、事件、事件總線等通信的方式的弊端就會愈發(fā)明顯。這個時候我們就需要 Vuex 。Vuex 是一個專門為 Vue 設計的狀態(tài)管理工具。

狀態(tài)管理是 Vue 組件解耦的重要手段。

它借鑒了 Flux、redux 的基本思想,將狀態(tài)抽離到全局,形成一個 Store。

 Vuex 不限制你的代碼結(jié)構(gòu),但需要遵守一些規(guī)則:

  • 應用層級的狀態(tài)應該集中到單個 store 對象中
  • 提交 mutation 是更改狀態(tài)的唯一方法,并且這個過程是同步的
  • 異步邏輯都應該封裝到 action 里面

 Vuex 注入 Vue 生命周期的過程

我們在安裝插件的時候,總會像下面一樣用 Vue.use() 來載入插件,可是 Vue.use() 做了什么呢?

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

Vue.use(Vuex);

Vue.use() 做了什么

安裝 Vue.js 插件。如果插件是一個對象,必須提供 install 方法。如果插件是一個函數(shù),它會被作為 install 方法。install 方法調(diào)用時,會將 Vue 作為參數(shù)傳入。

以上是官方文檔的解釋。

接下來我們從源碼部分來看看 Vue.use() 都做了什么。

Vue 源碼在 initGlobalAPI 入口方法中調(diào)用了 initUse (Vue) 方法,這個方法定義了 Vue.use() 需要做的內(nèi)容。

function initGlobalAPI (Vue) {
 ......
 initUse(Vue);
 initMixin$1(Vue); // 下面講 Vue.mixin 會提到
 ......
}

function initUse (Vue) {
 Vue.use = function (plugin) {
 var installedPlugins = (this._installedPlugins || (this._installedPlugins = []));
 /* 判斷過這個插件是否已經(jīng)安裝 */
 if (installedPlugins.indexOf(plugin) > -1) {
 return this
 }
 var args = toArray(arguments, 1);
 args.unshift(this);
 /* 判斷插件是否有 install 方法 */
 if (typeof plugin.install === 'function') {
 plugin.install.apply(plugin, args);
 } else if (typeof plugin === 'function') {
 plugin.apply(null, args);
 }
 installedPlugins.push(plugin);
 return this
 };
}

這段代碼主要做了兩件事情:

  1. 一件是防止重復安裝相同的 plugin
  2. 另一件是初始化 plugin

插件的 install 方法

看完以上源碼,我們知道插件(Vuex)需要提供一個 install 方法。那么我們看看 Vuex 源碼中是否有這個方法。結(jié)果當然是有的:

/* 暴露給外部的 install 方法 */
function install (_Vue) {
 /* 避免重復安裝(Vue.use 內(nèi)部也會檢測一次是否重復安裝同一個插件)*/
 if (Vue && _Vue === Vue) {
 {
 console.error(
 '[vuex] already installed. Vue.use(Vuex) should be called only once.'
 );
 }
 return
 }
 Vue = _Vue;
 /* 將 vuexInit 混淆進 Vue 的 beforeCreate(Vue2.0) 或 _init 方法(Vue1.0) */
 applyMixin(Vue);
}

這段代碼主要做了兩件事情:

  1. 一件是防止 Vuex 被重復安裝
  2. 另一件是執(zhí)行 applyMixin ,目的是執(zhí)行 vuexInit 方法初始化 Vuex

接下來 我們看看 applyMixin(Vue) 源碼:

/* 將 vuexInit 混淆進 Vue 的 beforeCreate */
function applyMixin (Vue) {
 var version = Number(Vue.version.split('.')[0]);
 if (version >= 2) {
 Vue.mixin({ beforeCreate: vuexInit });
 } else {
 /* Vue1.0 的處理邏輯,此處省略 */
 ......
 }
 function vuexInit () {
 ......
 }
}

從上面的源碼,可以看出 Vue.mixin 方法將 vuexInit 方法混淆進 beforeCreate 鉤子中,也是因為這個操作,所以每一個 vm 實例都會調(diào)用 vuexInit 方法。那么 vuexInit 又做了什么呢?

vuexInit()

我們在使用 Vuex 的時候,需要將 store 傳入到 Vue 實例中去。

new Vue({
 el: '#app',
 store
});

但是我們卻在每一個 vm 中都可以訪問該 store,這個就需要靠 vuexInit 了。

 function vuexInit () {
 const options = this.$options
 if (options.store) {
 /* 根節(jié)點存在 stroe 時 */
 this.$store = typeof options.store === 'function'
 ? options.store()
 : options.store
 } else if (options.parent && options.parent.$store) {
 /* 子組件直接從父組件中獲取 $store,這樣就保證了所有組件都公用了全局的同一份 store*/
 this.$store = options.parent.$store
 }
 }

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

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

Vue.mixin()

全局注冊一個混入,影響注冊之后所有創(chuàng)建的每個 Vue 實例。插件作者可以使用混入,向組件注入自定義的行為。 不推薦在應用代碼中使用。

在 vue 的 initGlobalAPI 入口方法中調(diào)用了 initMixin$1(Vue) 方法:

function initMixin$1 (Vue) {
 Vue.mixin = function (mixin) {
 this.options = mergeOptions(this.options, mixin);
 return this
 };
}

Vuex 注入 Vue 生命周期的過程大概就是這樣,如果你感興趣的話,你可以直接看看 Vuex 的源碼,接下來我們說說 Store。

Store

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

我們使用 Vuex 的時候都會定義一個和下面類似的 Store 實例。

import Vue from 'vue'
import Vuex from 'vuex'
import mutations from './mutations'

Vue.use(Vuex)

const state = {
 showState: 0,    
}

export default new Vuex.Store({
 strict: true,
	state,
	getters,
})

不要在發(fā)布環(huán)境下啟用嚴格模式。嚴格模式會深度監(jiān)測狀態(tài)樹來檢測不合規(guī)的狀態(tài)變更 —— 請確保在發(fā)布環(huán)境下關(guān)閉嚴格模式,以避免性能損失。

state 的響應式

你是否關(guān)心 state 是如何能夠響應式呢?這個主要是通過 Store 的構(gòu)造函數(shù)中調(diào)用的 resetStoreVM(this, state) 方法來實現(xiàn)的。

這個方法主要是重置一個私有的 _vm(一個 Vue 的實例) 對象。這個 _vm 對象會保留我們的 state 樹,以及用計算屬性的方式存儲了 store 的 getters?,F(xiàn)在具體看看它的實現(xiàn)過程。

/* 使用 Vue 內(nèi)部的響應式注冊 state */
function resetStoreVM (store, state, hot) {
 /* 存放之前的vm對象 */
 const oldVm = store._vm 

 store.getters = {}
 const wrappedGetters = store._wrappedGetters
 const computed = {}

 /* 通過 Object.defineProperty 方法為 store.getters 定義了 get 方法。當在組件中調(diào)用 this.$store.getters.xxx 這個方法的時候,會訪問 store._vm[xxx]*/
 forEachValue(wrappedGetters, (fn, key) => {
 computed[key] = partial(fn, store)
 Object.defineProperty(store.getters, key, {
 get: () => store._vm[key],
 enumerable: true // for local getters
 })
 })

 const silent = Vue.config.silent
 /* 設置 silent 為 true 的目的是為了取消 _vm 的所有日志和警告 */
 Vue.config.silent = true
 /* 這里new了一個Vue對象,運用Vue內(nèi)部的響應式實現(xiàn)注冊state以及computed*/
 store._vm = new Vue({
 data: {
 $$state: state
 },
 computed
 })
 Vue.config.silent = silent

 /* 使能嚴格模式,Vuex 中對 state 的修改只能在 mutation 的回調(diào)函數(shù)里 */
 if (store.strict) {
 enableStrictMode(store)
 }

 if (oldVm) {
 /* 解除舊 vm 的 state 的引用,并銷毀這個舊的 _vm 對象 */
 if (hot) {
 store._withCommit(() => {
 oldVm._data.$$state = null
 })
 }
 Vue.nextTick(() => oldVm.$destroy())
 }
}

state 的響應式大概就是這樣實現(xiàn)的,也就是初始化 resetStoreVM 方法的過程。

看看 Store 的 commit 方法

我們知道 commit 方法是用來觸發(fā) mutation 的。

commit (_type, _payload, _options) {
 /* unifyObjectStyle 方法校參 */
 const {
 type,
 payload,
 options
 } = unifyObjectStyle(_type, _payload, _options)

 const mutation = { type, payload }
 /* 找到相應的 mutation 方法 */
 const entry = this._mutations[type]
 if (!entry) {
 if (process.env.NODE_ENV !== 'production') {
 console.error(`[vuex] unknown mutation type: ${type}`)
 }
 return
 }
 /* 執(zhí)行 mutation 中的方法 */
 this._withCommit(() => {
 entry.forEach(function commitIterator (handler) {
 handler(payload)
 })
 })
 /* 通知所有訂閱者,傳入當前的 mutation 對象和當前的 state */
 this._subscribers.forEach(sub => sub(mutation, this.state))

 if (
 process.env.NODE_ENV !== 'production' &&
 options && options.silent
 ) {
 console.warn(
 `[vuex] mutation type: ${type}. Silent option has been removed. ` +
 'Use the filter functionality in the vue-devtools'
 )
 }
}

該方法先進行參數(shù)風格校驗,然后利用 _withCommit 方法執(zhí)行本次批量觸發(fā) mutation 處理函數(shù)。執(zhí)行完成后,通知所有 _subscribers (訂閱函數(shù))本次操作的 mutation 對象以及當前的 state 狀態(tài)。

以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Vue 根據(jù)條件判斷van-tab的顯示方式

    Vue 根據(jù)條件判斷van-tab的顯示方式

    這篇文章主要介紹了Vue 根據(jù)條件判斷van-tab的顯示方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-08-08
  • vue-admin-template解決登錄和跨域問題解決

    vue-admin-template解決登錄和跨域問題解決

    本文主要介紹了vue-admin-template解決登錄和跨域問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-05-05
  • 使用vue-cli搭建SPA項目的詳細過程

    使用vue-cli搭建SPA項目的詳細過程

    vue-cli是vue.js的腳手架,用于自動生成vue.js+webpack的項目模板,本文通過實例代碼給大家介紹vue-cli搭建SPA項目的詳細過程,感興趣的朋友跟隨小編一起看看吧
    2022-09-09
  • vue中的加密方式總結(jié)

    vue中的加密方式總結(jié)

    這篇文章主要為大家詳細介紹了vue中常見的加密方式實現(xiàn),例如js-base64、crypto-js、jsencrypt、bcryptjs,文中的示例代碼講解詳細,需要的小伙伴可以參考一下
    2023-11-11
  • Vue2?this?能夠直接獲取到?data?和?methods?的原理分析

    Vue2?this?能夠直接獲取到?data?和?methods?的原理分析

    這篇文章主要介紹了Vue2?this能夠直接獲取到data和methods的原理分析,因為methods里的方法通過bind指定了this為new?Vue的實例
    2022-06-06
  • 詳解Vue如何實現(xiàn)字母驗證碼

    詳解Vue如何實現(xiàn)字母驗證碼

    這篇文章主要為大家介紹了Vue如何實現(xiàn)字母驗證碼詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-05-05
  • 淺入深出Vue之自動化路由

    淺入深出Vue之自動化路由

    這篇文章主要介紹了淺入深出Vue之自動化路由,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-08-08
  • Vue3中emits與attrs的區(qū)別分析

    Vue3中emits與attrs的區(qū)別分析

    這篇文章主要給大家介紹了關(guān)于Vue3中emits與attrs區(qū)別的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用vue具有一定的參考學習價值,需要的朋友可以參考下
    2021-10-10
  • Element-plus封裝搜索組件的實現(xiàn)

    Element-plus封裝搜索組件的實現(xiàn)

    在后臺管理系統(tǒng)中,經(jīng)常需要在多個頁面中使用搜索功能,本文就來介紹一下Element-plus封裝搜索組件的實現(xiàn),具有一定的參考價值,感興趣的可以了解一下
    2024-08-08
  • vue+echarts實現(xiàn)動態(tài)繪制圖表及異步加載數(shù)據(jù)的方法

    vue+echarts實現(xiàn)動態(tài)繪制圖表及異步加載數(shù)據(jù)的方法

    vue寫的后臺管理,需要將表格數(shù)據(jù)繪制成圖表(折線圖,柱狀圖),圖表數(shù)據(jù)都是通過接口請求回來的。這篇文章主要介紹了vue+echarts 動態(tài)繪制圖表及異步加載數(shù)據(jù)的相關(guān)知識,需要的朋友可以參考下
    2018-10-10

最新評論