第一次寫博客,堅持了一個多月時間,Vue源碼分析基本分析完了,回過頭也看也漏了一些地方,比如雙向綁定里的觀察者模式,也可以說是訂閱者模式,也就是Vue里的Dep、Watcher等這些函數的作用,網上搜一下講解也挺多的,這些知識點也是很重要的,對於閱讀源碼的同學這一塊務必要花點時間學一下 還有一個挺重 ...
第一次寫博客,堅持了一個多月時間,Vue源碼分析基本分析完了,回過頭也看也漏了一些地方,比如雙向綁定里的觀察者模式,也可以說是訂閱者模式,也就是Vue里的Dep、Watcher等這些函數的作用,網上搜一下講解也挺多的,這些知識點也是很重要的,對於閱讀源碼的同學這一塊務必要花點時間學一下
還有一個挺重要是Vue的一個use和mixin方法,這兩個方法用於Vue插件的註冊,比如Vuex、Vuex-router等等都是通過Vue.use()來註冊的,註冊完後會執行對應插件的install方法進行安裝,例如對於Vuex來說:
if (version >= 2) { Vue.mixin({ beforeCreate: vuexInit }); //對於Vuex來說,通過mixin混入,在Vue的beforeCreate生命周期函數內插入一個vuexInit方法 } else { // override init and inject vuex init procedure // for 1.x backwards compatibility. var _init = Vue.prototype._init; Vue.prototype._init = function (options) { if ( options === void 0 ) options = {}; options.init = options.init ? [vuexInit].concat(options.init) : vuexInit; _init.call(this, options); }; }
對於Vue-router來說,如下:
Vue.mixin({ //對於Vue-router來說,通過mixin混入,在Vue的beforeCreate和destroyed生命周期函數內分別插入兩個函數體 beforeCreate: function beforeCreate () { if (isDef(this.$options.router)) { this._routerRoot = this; this._router = this.$options.router; this._router.init(this); Vue.util.defineReactive(this, '_route', this._router.history.current); } else { this._routerRoot = (this.$parent && this.$parent._routerRoot) || this; } registerInstance(this, this); }, destroyed: function destroyed () { registerInstance(this); } });
當我們執行Vue.use(Vuex)或者Vue.use(Router)安裝Vuex或Vue-router插件時,就會執行Vue內部的use函數介面,如下:
Vue.use = function (plugin) { //第4728行 註冊插件用 var installedPlugins = (this._installedPlugins || (this._installedPlugins = [])); //獲取當前Vue已經註冊的插件列表 if (installedPlugins.indexOf(plugin) > -1) { //如果plugin插件已經註冊過了 return this //直接返回,不做處理 } // additional parameters var args = toArray(arguments, 1); //去掉第一個參數 args.unshift(this); //然後將大Vue放進去 if (typeof plugin.install === 'function') { //如果有該插件有install方法 plugin.install.apply(plugin, args); //執行該install方法,參數為args(第一個參數為大Vue的實例) } else if (typeof plugin === 'function') { plugin.apply(null, args); } installedPlugins.push(plugin); //將插件plugin保存到installedPlugins裡面,避免多次執行Use時重覆安裝 return this };
也就是說執行插件的install函數時,函數內的上下文為Vue實例,然後就可以在Vue內部的生命周期內執行各種操作了,這就是插件的邏輯了。
mixin就是混入的意思,也就是把對象里的信息保存到Vue實例的options上,一般是混入一些生命周期函數,源碼就一行,保存到Vue實例的options上,我就不貼了。
從整體來看,Vue只是一個匿名函數,該函數會在window.Vue這個屬性上掛載一個函數,然後在該函數本身或函數原型上定義一些屬性、操作如此而已,只是Vue定義的屬性和操作比多,看起來複雜,例如Vue有一萬多行代碼,不只是Vue,大多話前端框架基本都是這個設計模式吧(通過執行一個匿名函數來給window掛載一個屬性作為調用的介面)。
理解源碼有一個好處就是用起來真的很爽,比如我現在工作用到Vue時就和算算術題1+1=2一樣,而且寫起代碼來沒有冗餘代碼,因為你知掉它是怎麼實現的了。