首頁 >web前端 >js教程 >vue源碼入口文件實例分析

vue源碼入口文件實例分析

小云云
小云云原創
2018-01-31 13:11:511572瀏覽

本文主要介紹了vue源碼入口文件分析(推薦),小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧,希望能幫助大家。

開發vue專案有一段時間了, 之前用angularjs 後來用reactjs 但是那時候一直沒有時間把自己看源碼的思考記錄下來,現在我不想再浪費這來之不易的思考,我要堅持! !

看原始碼我個人感覺很開心,每每看上一段,自己就充實許多,不知道你是否跟我一樣。

vue 原始碼是眾多module(模組)用 rollup 工具合併而成, 從package.json 中能夠看到。現在讓我們從github上下載vue項目,開始我們今天的「思考」。

我下載的原始碼版本是:"version": "2.5.7",

原始碼起始位置從這裡可以看到


"dev": "rollup -w -c build/config.js --environment TARGET:web-full-dev"

// 从build/config.js 中找到 TARGET: web-full-dev 这是运行和编译(支持现在的浏览器,由于里面大量应用了ES6-7)后的

 // Runtime+compiler development build (Browser)
 'web-full-dev': {
  entry: resolve('web/entry-runtime-with-compiler.js'),
  dest: resolve('dist/vue.js'),
  format: 'umd',
  env: 'development',
  alias: { he: './entity-decoder' },
  banner
 },

找到了開始檔案就是"web/entry-runtime-with-compiler.js", 然後我們一路找Vue 物件終於在「instance/index.js」中找到了:


// 这是Vue 的开始位置
function Vue (options) {
 // 判断如果是不是生产环境,且不是通过new关键字来创建对象的话,就在控制台打印一个warning
 if (process.env.NODE_ENV !== 'production' &&
  !(this instanceof Vue)
 ) {
  warn('Vue is a constructor and should be called with the `new` keyword')
 }
 this._init(options)
}

看似到這裡都結束了,因為我們目的就是找到開始位置,但我有個疑問,為什麼Vue需要這麼多層?


entry-runtime-with-compiler.js
->
runtime/index.js
->
core/index.js
->
instance/index.js

當我仔細看了原始碼後恍然大悟,我們先看看他們這些檔案都做了什麼:

(1)instance/index.js

從Vue 模組命名中能看出一些端倪, instance (實例) 。

這個檔案是Vue 物件的開始,同時也是Vue 原型鏈(prototype) 方法的集中檔案


// _init
initMixin(Vue)
// $set、$delete、$watch
stateMixin(Vue)
// $on、$once、$off、$emit
eventsMixin(Vue)
// _update、$forceUpdate、$destroy
lifecycleMixin(Vue)
// $nextTick、_render、以及多个内部调用的方法
renderMixin(Vue)

這些方法只有實例化了才能調用。

(2)core/index.js

這個檔案在Instance/index.js 建立和初步加工後,再次加工。 那他主要做了什麼呢? 我們不考慮運行環境


initGlobalAPI(Vue)

對,就呼叫了這個方法,很簡單明了吧--- "初始化全域介面",

讓我們走進initGlobalAPI 方法


export function initGlobalAPI (Vue: GlobalAPI) {
 // config
 const configDef = {}
 configDef.get = () => config
 // 在 非生产环境,如何修改了配置文件config里面的内容会提示警告
 if (process.env.NODE_ENV !== 'production') {
  configDef.set = () => {
   warn(
    'Do not replace the Vue.config object, set inpidual fields instead.'
   )
  }
 }
 // 定义config 属性, 监听变化
 Object.defineProperty(Vue, 'config', configDef)

 // exposed util methods.
 // NOTE: these are not considered part of the public API - avoid relying on
 // them unless you are aware of the risk.
 Vue.util = {
  warn,
  extend,
  mergeOptions,
  defineReactive
 }

 Vue.set = set
 Vue.delete = del
 Vue.nextTick = nextTick

 Vue.options = Object.create(null)
 // 给vue 创建 ASSET_TYPES 的 空对象
 ASSET_TYPES.forEach(type => {
  Vue.options[type + 's'] = Object.create(null)
 })

 // this is used to identify the "base" constructor to extend all plain-object
 // components with in Weex's multi-instance scenarios.
 Vue.options._base = Vue

 extend(Vue.options.components, builtInComponents)
 // Vue.use
 initUse(Vue)
 // Vue.mixin
 initMixin(Vue)
 // Vue.extend
 initExtend(Vue)
 // Vue.component, Vue.directive, Vue.filter
 initAssetRegisters(Vue)
}

這裡面基本上都是靜態方法,即:用Vue. xxx 的形式呼叫。

(3)runtime/index.js

這裡就加一些擴充和在Vue.prototype上加入了__patch__和$mount(掛載元素) 。


// Vue.options.directives(model和show)和 Vue.options.components(Transition和TransitionGroup)
extend(Vue.options.directives, platformDirectives)
extend(Vue.options.components, platformComponents)

// install platform patch function
Vue.prototype.__patch__ = inBrowser ? patch : noop

// public mount method
Vue.prototype.$mount = function (
 el?: string | Element,
 hydrating?: boolean
): Component {
 el = el && inBrowser ? query(el) : undefined
 return mountComponent(this, el, hydrating)
}

(4)entry-runtime-with-compiler.js

就乾了一件事就是重寫$mount, Vue依不同運行環境,重寫不同$mount


#
const mount = Vue.prototype.$mount
Vue.prototype.$mount = function (
 el?: string | Element,
 hydrating?: boolean
): Component {
 ...
 return mount.call(this, el, hydrating)
}

總結:

到此我們找到了開始執行的文件,和每個文件有什麼用,具體怎麼做的,做了什麼我會下次再寫。不過我們剛開始不要太在乎每個細節,不要再搞懂每一行程式碼,如果那樣,真的太累了,而且可能沒有勇氣堅持下去。

相關推薦:

webpack多重入口檔案頁面打包詳解

以上是vue源碼入口文件實例分析的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn