成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Vue源碼學(xué)習(xí)(二)——從宏觀看Vue

AndroidTraveler / 1241人閱讀

摘要:上一篇文章我們寫到從入口文件一步步找到的構(gòu)造函數(shù),現(xiàn)在我們要去看看實(shí)例化經(jīng)歷的過(guò)程的構(gòu)造函數(shù)我們知道的構(gòu)造函數(shù)在中不明白的可以去看上一篇文章源碼學(xué)習(xí)筆記一。

上一篇文章我們寫到從入口文件一步步找到Vue的構(gòu)造函數(shù),現(xiàn)在我們要去看看Vue實(shí)例化經(jīng)歷的過(guò)程
Vue的構(gòu)造函數(shù)

我們知道Vue的構(gòu)造函數(shù)在src/core/instance/index.js中,不明白的可以去看上一篇文章 Vue源碼學(xué)習(xí)筆記一。那我們關(guān)注一下Vue的構(gòu)造函數(shù)的內(nèi)容:

// src/core/instance/index.js

import { initMixin } from "./init"

// Vue的構(gòu)造函數(shù)
function Vue (options) {
  //... 驗(yàn)證環(huán)境
  this._init(options)
}

// 在Vue原型上綁定實(shí)例方法
initMixin(Vue)  // init
stateMixin(Vue)  // $set $delete $watch
eventsMixin(Vue)  // $on $once $off $emit
lifecycleMixin(Vue)  // _update $forceUpdate $destroy
renderMixin(Vue)  // $nextTick _render
添加Vue屬性和方法

這邊我們可以看到Vue的構(gòu)造函數(shù)中執(zhí)行了init方法,從下方得知init是在srccoreinstanceinit.js中導(dǎo)出的initMixin函數(shù)中定義的

initMixin

vmthis ,同時(shí)為實(shí)例添加一個(gè)唯一的uid, vm._isVue = true 監(jiān)聽(tīng)對(duì)象變化時(shí)用于過(guò)濾vm,因?yàn)閂ue的實(shí)例是不需要監(jiān)聽(tīng)變化的。

// src/core/instance/init.js
Vue.prototype._init = function (options?: Object) {
 const vm: Component = this

  // 當(dāng)前實(shí)例添加了一個(gè)唯一的uid
  vm._uid = uid++   

  // ...

  // 監(jiān)聽(tīng)對(duì)象變化時(shí)用于過(guò)濾vm
  vm._isVue = true
  
  //...
  }

參數(shù)處理,根據(jù)我們的小栗子,我們的options處理直接進(jìn)入了else,然后對(duì)參數(shù)進(jìn)行合并,這里是對(duì)vue extend的參數(shù)需要進(jìn)行合并處理,我們這里resolveConstructorOptions 返回的即是constructor.options本身

生命周期相關(guān)變量初始化 initLifecycle(vm)

 // srccoreinstancelifecycle.js
 
 // 為組件掛載相應(yīng)屬性,并初始化
  vm.$parent = parent
  vm.$root = parent ? parent.$root : vm

  vm.$children = []
  vm.$refs = {}

  vm._watcher = null
  vm._inactive = null
  vm._directInactive = false
  vm._isMounted = false
  vm._isDestroyed = false
  vm._isBeingDestroyed = false

4.vm 事件監(jiān)聽(tīng)初始化 initEvents()

// src/core/instance/events.js
export function initEvents (vm: Component) {
  // 創(chuàng)建事件對(duì)象,用于存儲(chǔ)事件
  vm._events = Object.create(null)
  // 系統(tǒng)事件標(biāo)識(shí)位
  vm._hasHookEvent = false
  
  // init parent attached events npm 
  // 將父組件模板中注冊(cè)的事件放到當(dāng)前組件實(shí)例的listeners
  const listeners = vm.$options._parentListeners
  if (listeners) {
    updateComponentListeners(vm, listeners)
  }
}
  initEvents(vm)
  initRender(vm)
  callHook(vm, "beforeCreate")
  initInjections(vm)  

  //  vm狀態(tài)初始化,prop/data/computed/method/watch都在這里初始化完成,vue實(shí)例create的關(guān)鍵
  initState(vm)
  initProvide(vm)  
  callHook(vm, "created")
stateMixin
Vue實(shí)例方法--數(shù)據(jù),該文件對(duì)應(yīng)的是Vue的數(shù)據(jù)的處理,首先對(duì)$data進(jìn)行掛載,然后設(shè)置數(shù)據(jù)$set、刪除數(shù)據(jù)$delete、觀測(cè)數(shù)據(jù)$watch方法掛載
// stateMixin(Vue)    src/core/instance/state.js
export function stateMixin (Vue: Class) {
  // data
  const dataDef = {}
  dataDef.get = function () { return this._data }
  // prop
  const propsDef = {}
  propsDef.get = function () { return this._props }

  // ...

  // 定義$data & prop屬性
  Object.defineProperty(Vue.prototype, "$data", dataDef)
  Object.defineProperty(Vue.prototype, "$props", propsDef)

  // 原型鏈添加函數(shù)set 和 delete
  Vue.prototype.$set = set
  Vue.prototype.$delete = del

  // 原型鏈添加函數(shù)$watch
  Vue.prototype.$watch = function (){
    // ...
  }
}
eventsMixin
Vue實(shí)例方法--事件,該文件主要掛載Vue實(shí)例方法的事件,監(jiān)聽(tīng)事件on once、移除事件off、觸發(fā)事件emit的掛載
// eventsMixin(Vue)    src/core/instance/events.js
export function eventsMixin (Vue: Class) {
  Vue.prototype.$on = function (event: string, fn: Function): Component {
    // ...
  } 
  Vue.prototype.$once = function (event: string, fn: Function): Component {
    // ...
  }
  Vue.prototype.$off = function (event?: string, fn?: Function): Component {
    // ...
  }
  Vue.prototype.$emit = function (event: string): Component {
    // ...
  }
}
lifecycleMixin
Vue實(shí)例方法--生命周期,,該文件主要掛載Vue實(shí)例方法中的生命周期方法,重新渲染$forceUpdate()、銷毀實(shí)例$destroy()
// lifecycleMixin(Vue)    src/core/instance/lifecycle.js
Vue.prototype._mount = function(){}
Vue.prototype._update = function (vnode: VNode, hydrating?: boolean) {}
Vue.prototype._updateFromParent = function(){}
Vue.prototype.$forceUpdate = function () {}
Vue.prototype.$destroy = function () {}
renderMixin
文件主要掛載Vue實(shí)例方法中的dom更新回調(diào)$nextTick及一些其他的render函數(shù),后續(xù)我們?cè)俚纳钔谝幌?/pre>
// renderMixin(Vue)    src/core/instance/render.js
Vue.prototype.$nextTick = function (fn: Function) {}
Vue.prototype._render = function (): VNode {}
Vue.prototype._s = _toString
Vue.prototype._v = createTextVNode
Vue.prototype._n = toNumber
Vue.prototype._e = createEmptyVNode
Vue.prototype._q = looseEqual
Vue.prototype._i = looseIndexOf
Vue.prototype._m = function(){}
Vue.prototype._o = function(){}
Vue.prototype._f = function resolveFilter (id) {}
Vue.prototype._l = function(){}
Vue.prototype._t = function(){}
Vue.prototype._b = function(){}
Vue.prototype._k = function(){}
全局API
上面部分,我們對(duì)Vue的構(gòu)造函數(shù),在src/core/instance/index.js文件中的作用進(jìn)行了大體的了解,當(dāng)然這并沒(méi)有結(jié)束,依據(jù)我們Vue源碼學(xué)習(xí)筆記一中提到的,我們追溯到上一級(jí)src/core/index.js
// src/core/index.js

import Vue from "./instance/index"
import { initGlobalAPI } from "./global-api/index"

import { isServerRendering } from "core/util/env"
import { FunctionalRenderContext } from "core/vdom/create-functional-component"

// 初始化全局變量
initGlobalAPI(Vue)

// 為vue原型定義屬性 isServer  判斷是否為服務(wù)端渲染
Object.defineProperty(Vue.prototype, "$isServer", {
  get: isServerRendering
})

// 為vue原型定義屬性 ssrContext
Object.defineProperty(Vue.prototype, "$ssrContext", {
  get () {
    /* istanbul ignore next */
    return this.$vnode && this.$vnode.ssrContext
  }
})

Object.defineProperty(Vue, "FunctionalRenderContext", {
  value: FunctionalRenderContext
})

Vue.version = "__VERSION__"

export default Vue
initGlobalAPI(Vue)
在Vue 構(gòu)造函數(shù)上掛載靜態(tài)屬性和方法即全局API
// src/core/global-api/index.js

export function initGlobalAPI(Vue: GlobalAPI) {
  const configDef = {}
  configDef.get = () => config
  // ...
  Object.defineProperty(Vue, "config", configDef)
  
  Vue.util = { // Vue.util
    warn,
    extend,
    mergeOptions,
    defineReactive
  }

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

  Vue.options = Object.create(null)
  ASSET_TYPES.forEach(type => {
    Vue.options[type + "s"] = Object.create(null)
  })

  Vue.options._base = Vue

  extend(Vue.options.components, builtInComponents)
  
  initUse(Vue)   // Vue.use

  initMixin(Vue)  // Vue.mixin

  initExtend(Vue) // Vue.extend
  
  initAssetRegisters(Vue) // Vue.component Vue.directive Vue.filter
}
內(nèi)置組件&命令
在追溯到上一級(jí),在文件src/platforms/web/runtime/index.js,該文件注冊(cè)了一些 Vue內(nèi)置的組件:包裹動(dòng)態(tài)組件KeepAlive、元素過(guò)渡效果Transition、多個(gè)元素過(guò)渡TransitionGroup
// src/platforms/web/runtime/index.js 執(zhí)行后

// 安裝平臺(tái)特定的utils
Vue.config.isUnknownElement = isUnknownElement
Vue.config.isReservedTag = isReservedTag
Vue.config.getTagNamespace = getTagNamespace
Vue.config.mustUseProp = mustUseProp
// 安裝平臺(tái)特定的 指令 和 組件
Vue.options = {
    components: {
        KeepAlive,
        Transition,
        TransitionGroup
    },
    directives: {
        model,
        show
    },
    filters: {},
    _base: Vue
}
Vue.prototype.__patch__
Vue.prototype.$mount
compiler編譯器添加
再上一級(jí)為src/platforms/web/entry-runtime-with-compiler.js,該文件對(duì)原來(lái)的Vue.prototype.$mount進(jìn)行覆蓋定義,并且在Vue上掛載了 compile。給Vue的 $mount 方法添加 compiler 編譯器,支持 template。
// src/platforms/web/entry-runtime-with-compiler.js
const mount = Vue.prototype.$mount

// ...
 
Vue.prototype.$mount = function (){

//... 覆蓋 Vue.prototype.$mount
}

// ...

//在 Vue 上掛載 compile 
//compileToFunctions 函數(shù)的作用,就是將模板 template 編譯為render函數(shù)。
Vue.compile = compileToFunctions
總結(jié)

至此的話我們從宏觀上過(guò)了一下從我們一層層找到vue到一層層往外看到對(duì)Vue的添加屬性方法等,我們有了一個(gè)整體的概念

src/core/instance/index.js vue的構(gòu)造函數(shù),添加Vue屬性和方法

src/core/index.js 全局API的掛載

src/platforms/web/runtime/index.js 主要是添加web平臺(tái)特有的配置、組件和指令

web/entry-runtime-with-compiler.js 給Vue的 $mount 方法添加 compiler 編譯器,支持 template

scripts/config.js 編譯入口文件

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/99898.html

相關(guān)文章

  • Vue源碼學(xué)習(xí)(一)——追根究底Vue

    摘要:其中執(zhí)行命令是我們當(dāng)前所關(guān)注的,對(duì)于項(xiàng)目的文件結(jié)構(gòu),我們需要去找到項(xiàng)目的啟動(dòng)的入口文件,接下來(lái)我們?nèi)ヒ徊揭徊降恼业椒治雒钍且粋€(gè)模塊打包器。 打算開(kāi)始學(xué)習(xí)vue的源碼開(kāi)始,我開(kāi)始 serach 關(guān)鍵詞:vue 源碼,可是發(fā)現(xiàn)很多都不是我想要看到的東西,所以打算記錄下來(lái),學(xué)習(xí)的記錄和日后分享。我在想這個(gè)文章的名字時(shí),手把手系列?十分鐘系列?小白到大佬系列?都不是,只是單純的學(xué)習(xí)筆記 文件...

    Harriet666 評(píng)論0 收藏0
  • Vue2.0—仿知乎日?qǐng)?bào)總結(jié)

    摘要:一個(gè)基于全家桶開(kāi)發(fā)的仿知乎日?qǐng)?bào)單頁(yè)應(yīng)用項(xiàng)目地址源碼地址項(xiàng)目在線地址在線地址模式下推薦使用移動(dòng)端模式瀏覽去觀看如果覺(jué)得做得還不錯(cuò)或者項(xiàng)目源碼對(duì)您有幫助希望您小抬右手到右上角點(diǎn)一個(gè)您的支持是作者長(zhǎng)期更新維護(hù)的動(dòng)力項(xiàng)目起源從二月份開(kāi)始學(xué)習(xí)學(xué)習(xí)了 Vue-News 一個(gè)基于vue全家桶開(kāi)發(fā)的仿知乎日?qǐng)?bào)單頁(yè)應(yīng)用 項(xiàng)目github地址:源碼地址 項(xiàng)目在線地址:在線地址 (PC模式下推薦使用chro...

    lentoo 評(píng)論0 收藏0
  • vue+vant同一項(xiàng)目實(shí)現(xiàn)豆瓣電影加網(wǎng)易云音樂(lè)webapp-最佳練手項(xiàng)目

    摘要:很多小伙伴練手都會(huì)去仿寫豆瓣電影或者網(wǎng)易云音樂(lè),所以,這回干脆把兩個(gè)集合起來(lái),具體長(zhǎng)什么樣,請(qǐng)各位看預(yù)覽或下面圖片啦。怎么折騰法呢比如豆瓣部分我使用了,網(wǎng)易云部分則沒(méi)有,網(wǎng)易的組件則是自己造的輪子,當(dāng)然在實(shí)際開(kāi)發(fā)中肯定不會(huì)這么搞啦。。 很多小伙伴練手都會(huì)去仿寫豆瓣電影或者網(wǎng)易云音樂(lè),所以,這回干脆把兩個(gè)集合起來(lái),具體長(zhǎng)什么樣,請(qǐng)各位看預(yù)覽或下面圖片啦。 目的: 做這個(gè)項(xiàng)目最主要的目的是...

    suosuopuo 評(píng)論0 收藏0
  • 聽(tīng)飛狐聊JavaScript設(shè)計(jì)模式系列13

    摘要:介一回聊狀態(tài)模式,官方描述允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變時(shí)改變它的行為。有限狀態(tài)機(jī)有限狀態(tài)機(jī)是一個(gè)非常有用的模型,可以模擬世界上大部分事物。這個(gè)是官方說(shuō)法,簡(jiǎn)單說(shuō),她有三個(gè)特征,狀態(tài)總數(shù)是有限的。,任一時(shí)刻,只處在一種狀態(tài)之中。 本回內(nèi)容介紹 上一回聊了聊組合模式(Composite),用組合模式模擬了個(gè)圖片庫(kù),聊了遞歸。介一回聊狀態(tài)模式(State),官方描述允許一個(gè)對(duì)象在其內(nèi)部狀態(tài)改...

    linkin 評(píng)論0 收藏0
  • Vue原理】Compile - 源碼版 之 Parse 主要流程

    寫文章不容易,點(diǎn)個(gè)贊唄兄弟 專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺(jué)得排版難看,請(qǐng)點(diǎn)擊 下面鏈接 或者 拉到 下面關(guān)注公眾號(hào)也可以吧 【Vue原理】Compile - 源碼版 之 Parse 主要流程 本文難度較繁瑣,需要耐心觀看,如果你對(duì) compile 源碼暫時(shí)...

    Forest10 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

AndroidTraveler

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<