最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Vue 2源碼解讀$mount函數(shù)原理

 更新時間:2022年08月15日 11:12:26   作者:MiyueFE  
這篇文章主要為大家介紹了Vue 2源碼解讀$mount原理示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

1. $mount 函數(shù)來源

上一節(jié)雖然直接從 core 目錄下找到了 Vue 的構(gòu)造函數(shù)定義,但是缺少 $mount 方法。所以直接從開發(fā)過程中使用的 vue.esm.js 找到對應(yīng)的源碼入口。

根據(jù) scripts/config.js 中可以找到 vue.esm.js 的構(gòu)建入口是 entry-runtime-with-compiler-esm.ts,這個文件沒有最終也是依賴的 runtime-with-compiler.ts。

這里放一下依賴關(guān)系:

// src/platforms/web/entry-runtime-with-compiler-esm.ts
import Vue from './runtime-with-compiler'
export default Vue
// src/platforms/web/runtime-with-compiler.ts
import Vue from './runtime/index'
const mount = Vue.prototype.$mount
Vue.prototype.$mount = function(el?: string | Element, hydrating?: boolean): Component {
  // ...
  const options = this.$options
  // ...
  return mount.call(this, el, hydrating)
}
Vue.compile = compileToFunctions
export default Vue
// src/platforms/web/runtime/index.ts
import Vue from 'core/index'
import { mountComponent } from 'core/instance/lifecycle'
import { patch } from './patch'
// ... 處理 Vue.config
// ... 處理 Vue.options
Vue.prototype.__patch__ = inBrowser ? patch : noop
Vue.prototype.$mount = function (el?: string | Element, hydrating?: boolean ): Component {
  el = el && inBrowser ? query(el) : undefined
  return mountComponent(this, el, hydrating)
}
export default Vue

src/platforms/web/runtime/index.ts 中對 Vue 構(gòu)造函數(shù)還做了其他處理,這里就先不看了。

2. runtime 運行時的 $mount 函數(shù)

src/platforms/web/runtime/index.ts 中定義的 $mount 函數(shù)就是調(diào)用了 mountComponent 方法并返回其結(jié)果,所以核心依然在 mountComponent 函數(shù)

2.1 mountComponent 函數(shù)

export function mountComponent(vm: Component, el: Element | null | undefined, hydrating?: boolean ): Component {
  vm.$el = el
  if (!vm.$options.render) {
    vm.$options.render = createEmptyVNode
    if (__DEV__) {
      // 這里是判斷開發(fā)環(huán)境,如果有配置模板或者el屬性,則警告需要將模板編譯成渲染函數(shù),或者使用包含編譯器的部分。
    }
  }
  callHook(vm, 'beforeMount')
  let updateComponent
  if (__DEV__ && config.performance && mark) {
    // 處理開發(fā)環(huán)境中,配置了 性能分析時的處理,會在組件中創(chuàng)建對應(yīng)的dom標(biāo)簽(class)
  } else {
    updateComponent = () => {
      vm._update(vm._render(), hydrating)
    }
  }
  // 渲染watcher,在執(zhí)行前觸發(fā) beforeUpdate 調(diào)用對應(yīng)鉤子函數(shù)
  const watcherOptions: WatcherOptions = {
    before() {
      if (vm._isMounted && !vm._isDestroyed) {
        callHook(vm, 'beforeUpdate')
      }
    }
  }
  new Watcher( vm, updateComponent, noop, watcherOptions, true)
  hydrating = false
  // 這個是配合 2.7 添加的 setup 處理
  const preWatchers = vm._preWatchers
  if (preWatchers) {
    for (let i = 0; i < preWatchers.length; i++) {
      preWatchers[i].run()
    }
  }
  // 手動掛載實例,并且在首次掛載($vnode為空)時觸發(fā) mounted
  if (vm.$vnode == null) {
    vm._isMounted = true
    callHook(vm, 'mounted')
  }
  return vm
}

這里的邏輯也比較簡單(省略掉了性能分析)

  • 首先判斷 render 渲染函數(shù),沒有則將 render 屬性配置為一個創(chuàng)建空節(jié)點的函數(shù)
  • 調(diào)用在 lifecycleMixin(Vue) 中定義的 _update 方法來對比和更新 VNode,并渲染到 dom 節(jié)點上
  • 實例化一個 Render Watcher ,并在每次更新 dom 之前觸發(fā) beforeUpdate
  • 在2.7+版本,根據(jù) setup 中定義的預(yù)執(zhí)行的 watcher 函數(shù)分別調(diào)用 watcher.run 執(zhí)行一次
  • 最后修改實例狀態(tài) _isMounted,并觸發(fā) mounted,返回組件實例對象

2.2 _update 函數(shù)(首次渲染)

函數(shù)大致代碼如下

  Vue.prototype._update = function (vnode: VNode, hydrating?: boolean) {
    const vm: Component = this
    const prevEl = vm.$el
    const prevVnode = vm._vnode
    const restoreActiveInstance = setActiveInstance(vm)
    vm._vnode = vnode
    if (!prevVnode) {
      // 首次渲染
      vm.$el = vm.__patch__(vm.$el, vnode, hydrating, false /* removeOnly */)
    } else {
      // 更新
      vm.$el = vm.__patch__(prevVnode, vnode)
    }
    restoreActiveInstance()
    prevEl && (prevEl.__vue__ = null)
    vm.$el && (vm.$el.__vue__ = vm)
    // if parent is an HOC, update its $el as well
    if (vm.$vnode && vm.$parent && vm.$vnode === vm.$parent._vnode) {
      vm.$parent.$el = vm.$el
    }
  }

這里主要是記錄組件實例在更新前的 el** 和 **_vnode** 兩個屬性,用來在后面的 `__path__` 方法中進行比較和更新(也就是常說的 diff),最后將實例的 **el 屬性的 __vue__ 指向當(dāng)前實例,并處理高階函數(shù)組件的正確dom。

???? 這里通過 setActiveInstance(vm) 函數(shù),用閉包的形式將 當(dāng)前組件實例 導(dǎo)出到了外部,后面的 patch 使用的實例也就是該實例(translation 組件也會使用該實例)

3. runtime-with-compiler 的 $mount 函數(shù)

上文說到了 runtime-with-compiler.ts 中對 Vue 構(gòu)造函數(shù)上的 mount∗∗函數(shù)進行了重寫,并且原始的∗∗mount** 函數(shù)進行了重寫,并且原始的 **mount∗∗函數(shù)進行了重寫,并且原始的∗∗mount 函數(shù)也會在執(zhí)行時進行相關(guān)檢查。

const mount = Vue.prototype.$mount
Vue.prototype.$mount = function (el?: string | Element, hydrating?: boolean ): Component {
  el = el && query(el)
  if (el === document.body || el === document.documentElement) {
    __DEV__ &&  warn(`Do not mount Vue to <html> or <body> - mount to normal elements instead.`)
    return this
  }
  const options = this.$options
  if (!options.render) {
    let template = options.template
    if (template) {
      // 區(qū)分template的類型并驗證,最后轉(zhuǎn)成字符串
    } else if (el) {
      template = getOuterHTML(el)
    }
    // 根據(jù) template 字符串生成一個 render 函數(shù)
    if (template) {
      const { render, staticRenderFns } = compileToFunctions(
        template,
        {
          outputSourceRange: __DEV__,
          shouldDecodeNewlines,
          shouldDecodeNewlinesForHref,
          delimiters: options.delimiters,
          comments: options.comments
        },
        this
      )
      options.render = render
      options.staticRenderFns = staticRenderFns
    }
  }
  return mount.call(this, el, hydrating)
}

這里的作用其實就是編譯 template 模板的過程,并且在函數(shù)執(zhí)行時會檢查掛載的dom節(jié)點類型,不能掛載到 body 或者 html 上。

因為本身的 mount 方法(也就是 mountComponent)只能使用 vm.render() 生成的 VNode 來進行 patch 和生成真實 dom。

4. runtime 對 Vue 構(gòu)造函數(shù)的其他修改

上面說的 runtime/index.ts 中第一次定義了 Vue 上的 _mount 方法和 __patch__ 方法;同時,這里還在 Vue 構(gòu)造函數(shù)上增加了其他方法。

// 定義 web 端特定的工具函數(shù)
Vue.config.mustUseProp = mustUseProp
Vue.config.isReservedTag = isReservedTag
Vue.config.isReservedAttr = isReservedAttr
Vue.config.getTagNamespace = getTagNamespace
Vue.config.isUnknownElement = isUnknownElement
// 定義相關(guān)指令和組件
extend(Vue.options.directives, platformDirectives)
extend(Vue.options.components, platformComponents)

上面的幾個方法主要有以下作用:

mustUseProp: 定義哪些dom元素必須使用 props 綁定參數(shù)(默認有 input,option,select 等)

isReservedTag:判斷標(biāo)簽是不是默認保留的標(biāo)簽

isReservedAttr:判斷是不是標(biāo)簽保留屬性,這里只有 class 和 style

getTagNamespace:判斷標(biāo)簽的類別,這里只區(qū)分 SVG 元素和 math 標(biāo)簽

isUnknownElement:判斷未知元素

然后定義了以下指令和方法:

注冊 v-model 和 v-show 指令

注冊 Transition 和 TransitionGroup 動畫組件

以上就是Vue 2源碼解讀$mount函數(shù)原理的詳細內(nèi)容,更多關(guān)于Vue 2 $mount函數(shù)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • vue3.0關(guān)閉eslint校驗的3種方法詳解

    vue3.0關(guān)閉eslint校驗的3種方法詳解

    這篇文章主要給大家介紹了關(guān)于vue3.0關(guān)閉eslint校驗的3種方法,在實際開發(fā)過程中,eslint的作用不可估量,文中將關(guān)閉的方法介紹的非常詳細,需要的朋友可以參考下
    2023-06-06
  • vue+highcharts實現(xiàn)3D餅圖效果

    vue+highcharts實現(xiàn)3D餅圖效果

    這篇文章主要為大家詳細介紹了vue+highcharts實現(xiàn)3D餅圖效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • vue中的slot封裝組件彈窗

    vue中的slot封裝組件彈窗

    這篇文章主要介紹了vue中的slot封裝組件彈窗,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-05-05
  • vue中的rules表單校驗規(guī)則使用方法示例詳解 :rules=“rules“

    vue中的rules表單校驗規(guī)則使用方法示例詳解 :rules=“rules“

    這篇文章主要介紹了vue中的rules表單校驗規(guī)則使用方法示例詳解 :rules=“rules“,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-11-11
  • Vue使用xlsx插件導(dǎo)出excel文件的詳細指南

    Vue使用xlsx插件導(dǎo)出excel文件的詳細指南

    第三方庫xlsx提供了強大的功能來處理Excel文件,它可以簡化導(dǎo)出Excel文件這個過程,下面小編就來為大家詳細講講Vue如何通過xlsx導(dǎo)出excel,需要的小伙伴可以了解下
    2025-04-04
  • Vue利用Mixin輕松實現(xiàn)代碼復(fù)用

    Vue利用Mixin輕松實現(xiàn)代碼復(fù)用

    Mixin,中文翻譯為"混入",在Vue中是一種非常有用的功能,可以解決許多開發(fā)中的常見問題,下面就讓我們一起深入了解一下Mixin在Vue中解決了哪些問題吧
    2023-06-06
  • nextTick能否獲取到最新dom原理解析

    nextTick能否獲取到最新dom原理解析

    這篇文章主要為大家介紹了nextTick能否獲取到最新dom原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-11-11
  • Vue3中refs使用方法舉例

    Vue3中refs使用方法舉例

    在Vue中Refs是對DOM元素或已安裝到DOM的其他組件實例的引用,下面這篇文章主要給大家介紹了關(guān)于Vue3中refs使用的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-08-08
  • 一篇文章教你簡單使用Vue的watch偵聽器

    一篇文章教你簡單使用Vue的watch偵聽器

    這篇文章主要為大家介紹了Vue watch偵聽器,具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-12-12
  • Vue Vine實現(xiàn)一個文件中寫多個組件的方法(最近很火)

    Vue Vine實現(xiàn)一個文件中寫多個組件的方法(最近很火)

    Vue Vine提供了全新Vue組件書寫方式,主要的賣點是可以在一個文件里面寫多個vue組件,Vue Vine是一個vite插件,vite解析每個模塊時都會觸發(fā)插件的transform鉤子函數(shù),本文介紹Vue Vine是如何實現(xiàn)一個文件中寫多個組件,感興趣的朋友一起看看吧
    2024-07-07

最新評論

武穴市| 台中市| 英山县| 松滋市| 永吉县| 普格县| 额尔古纳市| 奎屯市| 巢湖市| 连南| 孙吴县| 晋宁县| 荆门市| 招远市| 成安县| 桦川县| 余姚市| 垦利县| 山阳县| 巴林右旗| 岳阳市| 丰都县| 垫江县| 临高县| 大渡口区| 鲁甸县| 峨山| 中卫市| 越西县| 上蔡县| 肥城市| 盱眙县| 抚顺市| 榆中县| 恩平市| 双桥区| 安福县| 平顶山市| 清苑县| 甘洛县| 嵊州市|