日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

vue render函数_Vue原理解析(一):Vue到底是什么?

發(fā)布時間:2023/12/9 vue 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 vue render函数_Vue原理解析(一):Vue到底是什么? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Vue,現(xiàn)在前端的當紅炸子雞,隨著熱度指數(shù)上升,實在是有必要從源碼的角度,對它功能的實現(xiàn)原理一窺究竟。個人覺得看源碼主要是看兩樣東西,從宏觀上來說是它的設(shè)計思想和實現(xiàn)原理;微觀上來說就是編程技巧,也就是俗稱的騷操作。我們這次的側(cè)重點是它的實現(xiàn)原理。好吧,讓我們推開它那神秘的大門,進入Vue的世界~

vue是什么?

vue究竟是什么?為什么就能實現(xiàn)這么多酷炫的功能,不知道大家有沒有思考過這個問題。其實在每次初始化vue,使用new Vue({...})時,不難發(fā)現(xiàn)vue其實是一個類。不過即使在ES6已經(jīng)如此普及的今天,vue的定義卻是普通構(gòu)造函數(shù)定義的,為什么沒有采用ES6的class呢?這個我們稍后回答,通過層層追蹤終于找到了vue被定義的地方:

function Vue(options) {...this._init(options) }

因為是原理解析,flow的類型檢測及一些邊界情況,如使用方式不對或參數(shù)不對或不是主要邏輯的代碼我們就省略掉吧。比如省略號這里邊界情況是使用時必須是new Vue()的形式,否則會報錯。

其實vue源碼就像一棵樹,我們看之前最好要確定看什么功能,然后避開那些分叉邏輯,我們接下來的目標就是以new Vue()開始,走完一整條從初始化、數(shù)據(jù)、模板到真實Dom的這整個流程。

這就是vue最初始被定義的地方,你沒看錯,就是這么簡單。當執(zhí)行new Vue時,內(nèi)部會執(zhí)行一個方法 this._init(options),將初始化的參數(shù)傳入。

這里需要說明一點,在vue的內(nèi)部,_符號開頭定義的變量是供內(nèi)部私有使用的,而$ 符號定義的變量是供用戶使用的,而且用戶自定義的變量不能以_或$開頭,以防止內(nèi)部沖突。我們接著看:

import { initMixin } from './init' import { stateMixin } from './state' import { renderMixin } from './render' import { eventsMixin } from './events' import { lifecycleMixin } from './lifecycle'function Vue(options) {...this._init(options) }initMixin(Vue) stateMixin(Vue) eventsMixin(Vue) lifecycleMixin(Vue) renderMixin(Vue)

現(xiàn)在可以回答之前的問題了,為什么不采用ES6的class來定義,因為這樣可以方便的把vue的功能拆分到不同的目錄中去維護,將vue的構(gòu)造函數(shù)傳入到以下方法內(nèi): initMixin(Vue):定義_init方法。 stateMixin(Vue):定義數(shù)據(jù)相關(guān)的方法$set,$delete,$watch方法。 eventsMixin(Vue):定義事件相關(guān)的方法$on,$once,$off,$emit。 lifecycleMixin(Vue):定義_update,及生命周期相關(guān)的$forceUpdate和$destroy。 * renderMixin(Vue):定義$nextTick,_render將render函數(shù)轉(zhuǎn)為vnode。

這些方法都是在各自的文件內(nèi)維護的,從而讓代碼結(jié)構(gòu)更加清晰易懂可維護。如this._init方法被定義在:

export function initMixin(Vue) {Vue.prototype._init = function(options) {...當執(zhí)行new Vue時,進行一系列初始化并掛載} }

再這些xxxMixin完成后,接著會定義一些全局的API:

export function initGlobalAPI(Vue) {Vue.set方法Vue.delete方法Vue.nextTick方法...內(nèi)置組件:keep-alivetransitiontransition-group...initUse(Vue):Vue.use方法initMixin(Vue):Vue.mixin方法initExtend(Vue):Vue.extend方法initAssetRegisters(Vue):Vue.component,Vue.directive,Vue.filter方法 }

這里有部分API和xxxMixin定義的原型方法功能是類似或相同的,如this.$set和Vue.set他們都是使用set這樣一個內(nèi)部定義的方法。

這里需要提一下vue的架構(gòu)設(shè)計,它的架構(gòu)是分層式的。最底層是一個ES5的構(gòu)造函數(shù),再上層在原型上會定義一些_init、$watch、_render等這樣的方法,再上層會在構(gòu)造函數(shù)自身定義全局的一些API,如set、nextTick、use等(以上這些是不區(qū)分平臺的核心代碼),接著是跨平臺和服務(wù)端渲染(這些暫時不在討論范圍)及編譯器。將這些屬性方法都定義好了之后,最后會導出一個完整的構(gòu)造函數(shù)給到用戶使用,而new Vue就是啟動的鑰匙。這就是我們陌生且又熟悉的vue,至于Vue.prototype._init內(nèi)部做了啥?我們下章節(jié)再說吧,因為還有很多其他的要補充。

目錄結(jié)構(gòu)

剛才是從比較微觀的角度近距離的觀察了vue,現(xiàn)在我們從宏觀角度來了解它內(nèi)部的代碼結(jié)構(gòu)是如何組建起來的。 目錄如下:

|-- dist 打包后的vue版本 |-- flow 類型檢測,3.0換了typeScript |-- script 構(gòu)建不同版本vue的相關(guān)配置 |-- src 源碼|-- compiler 編譯器|-- core 不區(qū)分平臺的核心代碼|-- components 通用的抽象組件|-- global-api 全局API|-- instance 實例的構(gòu)造函數(shù)和原型方法|-- observer 數(shù)據(jù)響應式|-- util 常用的工具方法|-- vdom 虛擬dom相關(guān)|-- platforms 不同平臺不同實現(xiàn)|-- server 服務(wù)端渲染|-- sfc .vue單文件組件解析|-- shared 全局通用工具方法 |-- test 測試
  • flow:javaScript是弱類型語言,使用flow以定義類型和檢測類型,增加代碼的健壯性。
  • src/compiler:將template模板編譯為render函數(shù)。
  • src/core:與平臺無關(guān)通用的邏輯,可以運行在任何javaScript環(huán)境下,如web、Node.js、weex嵌入原生應用中。
  • src/platforms:針對web平臺和weex平臺分別的實現(xiàn),并提供統(tǒng)一的API供調(diào)用。
  • src/observer:vue檢測數(shù)據(jù)數(shù)據(jù)變化改變視圖的代碼實現(xiàn)。
  • src/vdom:將render函數(shù)轉(zhuǎn)為vnode從而patch為真實dom以及diff算法的代碼實現(xiàn)。
  • dist:存放著針對不同使用方式的不同的vue版本。

vue版本

vue使用的是rollup構(gòu)建的,具體怎么構(gòu)建的不重要,總之會構(gòu)建出很多不同版本的vue。按照使用方式的不同,可以分為以下三類: UMD:通過<script>標簽直接在瀏覽器中使用。 CommonJS:使用比較舊的打包工具使用,如webpack1。 * ES Module:配合現(xiàn)代打包工具使用,如webpack2及以上。

而每個使用方式內(nèi)又分為了完整版和運行時版本,這里主要以ES Module為例,有了官方腳手架其他兩類應該沒多少人用了。再說明這兩個版本的區(qū)別之前,抱歉我又要補充點其他的。在vue的內(nèi)部是只認render函數(shù)的,我們來自己定義一個render函數(shù),也就是這么個東西:

new Vue({data: {msg: 'hello Vue!'},render(h) {return h('span', this.msg);} }).$mount('#app');

可能有人會納悶了,既然只認render函數(shù),同時我們開發(fā)好像從來并沒有寫過render函數(shù),而是使用的template模板。這是因為有vue-loader,它會將我們在template內(nèi)定義的內(nèi)容編譯為render函數(shù),而這個編譯就是區(qū)分完整版和運行時版本的關(guān)鍵所在,完整版就自帶這個編譯器,而運行時版本就沒有,如下面這段代碼如果是在運行時版本環(huán)境下就會報錯了:

new Vue({data: {msg: 'hello Vue!' },template: `<div>{{msg}}</div>` })

vue-cli默認是使用運行時版本的,更改或覆蓋腳手架內(nèi)的默認配置,將其更改為完整版即可通過編譯:'vue$': 'vue/dist/vue.esm.js',推薦還是使用運行時版本。好吧,具體區(qū)別最后我們以一個面試時經(jīng)常會被問到的問題作為本章節(jié)的結(jié)束。

面試官微笑而又不失禮貌的問到: * 請問runtime和runtime-only這兩個版本的區(qū)別? 懟回去:
  • 主要是兩點不同:
  • 最明顯的就是大小的區(qū)別,帶編譯器會比不帶的版本大6kb。
  • 編譯的時機不同,編譯器是運行時編譯,性能會有一定的損耗;運行時版本是借助loader做的離線編譯,運行性能更高。

順手點個贊或關(guān)注唄,找起來也方便~

胡成:你可能會用的上的一個vue功能組件庫,持續(xù)完善中...?zhuanlan.zhihu.com

總結(jié)

以上是生活随笔為你收集整理的vue render函数_Vue原理解析(一):Vue到底是什么?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。