首頁 >web前端 >js教程 >vue源碼架構的解讀(詳細)

vue源碼架構的解讀(詳細)

不言
不言轉載
2019-01-24 10:03:053291瀏覽

這篇文章帶給大家的內容是關於vue源碼架構的解讀(詳細),有一定的參考價值,有需要的朋友可以參考一下,希望對你有幫助。

下載

去github上下載Vue

npm install 
npm run dev

運行起來

rollup flow

vue使用使用rollup打包,flow規範資料型別

rollup可以先用webpack套用,讀起來差不多,時間有限,畢竟只有5分鐘,這篇就不用去看rollup文件了

入口

開package.json
我們看scripts設定

 "dev": "rollup -w -c scripts/config.js --environment TARGET:web-full-dev",
  "dev:cjs": "rollup -w -c scripts/config.js --environment TARGET:web-runtime-cjs-dev",

找到scripts /config.js
開啟

根據配置TARGET的不同會選擇不同的config

#同時在這裡設定了process.env.NODE_ENV 環境

TARGET有CommonJS ,ES Modules,UMD關於js引入類型的
還有weex,ssr

'web-runtime-cjs-dev': {
    entry: resolve('web/entry-runtime.js'),
    dest: resolve('dist/vue.runtime.common.dev.js'),
    format: 'cjs',
    env: 'development',
    banner
  }

在alias.js下設定了別名路徑
我們先介紹src/platforms

裡面有web和weex 分別的web和weex入口

在web檔案下是CommonJS,ES Modules,UMD關於js引入類型,server的打包入口

打開web/entry-runtime.js
引入

import Vue from './runtime/index'

export default Vue

開啟./runtime/index

import Vue from 'core/index'

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

在vue原型上加入了mount方法
處理了devtools,沒有安裝提醒安裝devtools

給了這句提示dev環境提示

You are running Vue in development mode.
Make sure to turn on production mode when deploying for production.
See more tips at https://vuejs.org/guide/deployment.html

platforms目錄夾講解完畢

core目錄

打開core/instance/index
映入眼前的是

function Vue (options) {
  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)
}

initMixin(Vue)
stateMixin(Vue)
eventsMixin(Vue)
lifecycleMixin(Vue)
renderMixin(Vue)

export default Vue

先執行的是initMixin(Vue)

開啟init

export function initMixin (Vue) {
  Vue.prototype._init = function (options?: Object) {
    const vm = this
    // a uid 
    vm._uid = uid++
    
    let startTag, endTag
    /* istanbul ignore if */
    if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
      startTag = `vue-perf-start:${vm._uid}`
      endTag = `vue-perf-end:${vm._uid}`
      mark(startTag)
    }

    // a flag to avoid this being observed
    vm._isVue = true
    // 处理传入的options
    // merge options
    if (options && options._isComponent) {
      // optimize internal component instantiation
      // since dynamic options merging is pretty slow, and none of the
      // internal component options needs special treatment.
      initInternalComponent(vm, options)
    } else {
       // 传入的options,默认的options一起合并挂载到vm.$options上
      vm.$options = mergeOptions(
        resolveConstructorOptions(vm.constructor),
        options || {},
        vm
      )
    }
    /* istanbul ignore else */
    if (process.env.NODE_ENV !== 'production') {
      // 代理
      initProxy(vm)
    } else {
      vm._renderProxy = vm
    }
    // 生命周期
    initLifecycle(vm)
     // emit on 事件
    initEvents(vm)
    // 处理render vdom
    initRender(vm)
    callHook(vm, 'beforeCreate')
    // 处理Injections
    initInjections(vm) // resolve injections before data/props
    // 双向数据绑定,监听订阅
    initState(vm)
    initProvide(vm) // resolve provide after data/props
    callHook(vm, 'created')
    
    /* istanbul ignore if */
    if (process.env.NODE_ENV !== 'production' && config.performance && mark) {
      vm._name = formatComponentName(vm, false)
      mark(endTag)
      measure(`vue ${vm._name} init`, startTag, endTag)
    }
    // 渲染到dom
    if (vm.$options.el) {
      vm.$mount(vm.$options.el)
    }
  }
}

lifecycle

開啟lifecycle

export function callHook (vm: Component, hook: string) {
  // disable dep collection when invoking lifecycle hooks
  pushTarget()
  //执行对象的周期函数,周期函数最后被处理成数组
  const handlers = vm.$options[hook]
  const info = `${hook} hook`
  if (handlers) {
    for (let i = 0, j = handlers.length; i <p>callHook 的時候,是執行對應週期,開發者在週期函數裡所寫的</p><h3>Events</h3><p>initEvents實作了emit on 等方法,請參考監聽者訂閱者模式,這裡不詳解</p><h3># render</h3><h4>renderMixin函數</h4><p>新增了 $nextTick  _render  原型物件</p><p>$nextTick會在dom跟新後立即呼叫</p><p>nextTick(fn, this)是一個自執行函數</p><p>_render回傳的是node的js數據,還不是dom</p><p>#做了Vdom</p><h4>initRender函數</h4><p>給vm添加了_c和$createElement用來渲染的方法</p><h3>state</h3><pre class="brush:php;toolbar:false">if (!(key in vm)) {
      proxy(vm, `_props`, key)
    }

給vue屬性做代理,存取this.a可以得到this.data.a 的值

export function initState (vm: Component) {
  vm._watchers = []
  const opts = vm.$options
  if (opts.props) initProps(vm, opts.props)
  if (opts.methods) initMethods(vm, opts.methods)
  if (opts.data) {
    initData(vm)
  } else {
    observe(vm._data = {}, true /* asRootData */)
  }
  if (opts.computed) initComputed(vm, opts.computed)
  if (opts.watch && opts.watch !== nativeWatch) {
    initWatch(vm, opts.watch)
  }
}

為資料做監聽

stateMixin函數

新增原型物件

 Vue.prototype.$set = set
 Vue.prototype.$delete = del

其他

src/compiler 做了編譯處理

#core/ componetd 做了keep-alive

core/util 封裝了通用方法

core/vdom vdom演算法

以上整體架構分析完畢

#附張圖
vue源碼架構的解讀(詳細)

#

以上是vue源碼架構的解讀(詳細)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除