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

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

vue是什么?

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

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

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

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

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

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

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)

現在可以回答之前的問題了,為什么不采用ES6class來定義,因為這樣可以方便的把vue的功能拆分到不同的目錄中去維護,將vue的構造函數傳入到以下方法內: initMixin(Vue):定義_init方法。 stateMixin(Vue):定義數據相關的方法$set,$delete,$watch方法。 eventsMixin(Vue):定義事件相關的方法$on$once$off$emit lifecycleMixin(Vue):定義_update,及生命周期相關的$forceUpdate$destroy。 * renderMixin(Vue):定義$nextTick_render將render函數轉為vnode

這些方法都是在各自的文件內維護的,從而讓代碼結構更加清晰易懂可維護。如this._init方法被定義在:

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

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

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

這里有部分APIxxxMixin定義的原型方法功能是類似或相同的,如this.$setVue.set他們都是使用set這樣一個內部定義的方法。

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

目錄結構

剛才是從比較微觀的角度近距離的觀察了vue,現在我們從宏觀角度來了解它內部的代碼結構是如何組建起來的。 目錄如下:

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

vue版本

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

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

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

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

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

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

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

順手點個贊或關注唄,找起來也方便~

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

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/396742.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/396742.shtml
英文地址,請注明出處:http://en.pswp.cn/news/396742.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

scrapy爬蟲-setting.py

# Obey robots.txt rulesROBOTSTXT_OBEY False  不遵從網站的robots.txt法則 # See also autothrottle settings and docsDOWNLOAD_DELAY 3  每次下載延遲3秒&#xff0c;防止造成網站攻擊 # Override the default request headers:DEFAULT_REQUEST_HEADERS { Accept:…

android點擊左上角劃出,使用Android中的Path和RectF在左上角右上角左下角繪制圓角...

有一個Path#addRoundRect()重載,它接受一個包含八個值的float數組,其中我們可以為四個角中的每一個指定x和y半徑.這些值為[x,y]對,從左上角開始,順時針繞其余部分.對于我們想要舍入的那些角,我們將該對的兩個值都設置為半徑值,并將它們保留為零,而不是那些.作為一個說明性示例,…

Nodejs微信開發

因為使用了Bot Framework開發了一個小功能&#xff0c;它目前支持了Skype\Teams\Slack等&#xff0c;但在國內來講&#xff0c;微信還是一個比較流行的軟件&#xff0c;所以需要接上微信 原來開發Bot的時候使用的是.Net開發的&#xff0c;這次我決定使用Nodejs開發一個簡單的后…

性別有什么用_為啥不讓男孩玩布娃娃?別讓你的“性別偏見”,給孩子的人生設限...

在養育孩子的過程中&#xff0c;父母總是會犯許多錯誤&#xff0c;更是有一些錯誤會直接使孩子毀掉一生&#xff0c;而性別偏見正是很多家長都會去犯的錯誤&#xff0c;對男孩和女孩有著刻板印象&#xff0c;也正是因為這一點使孩子的潛力和天賦被壓制。前幾天我帶著孩子去逛商…

android的時間代碼怎么寫,Android 日期和時間的使用實例詳解

Android 日期和時間的使用日期和時間的使用&#xff1b;1&#xff1a;彈出框TimePickerDialog,DatePickerDialog2&#xff1a;組件TimePicker,DatePickerTimePickerDialog的使用&#xff1a;通過點擊button顯示圖一&#xff0c;然后用戶可以設置時間DatePickerDialog的使用只需…

andriod studio 查看項目依賴_Intellij IDEA 中如何查看maven項目中所有jar包的依賴關系圖...

Maven 組件界面介紹如上圖標注 1 所示&#xff0c;為常用的 Maven 工具欄&#xff0c;其中最常用的有&#xff1a;第一個按鈕&#xff1a;Reimport All Maven Projects 表示根據 pom.xml 重新載入項目。一般單我們在 pom.xml 添加了依賴包或是插件的時候&#xff0c;發現標注 4…

Springboot 2.0.0單元測試

1. 引入spring-boot-starter-test包 1 <?xml version"1.0" encoding"UTF-8"?>2 <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"3 xsi:schemaLocation"…

SPRING IN ACTION 第4版筆記-第二章-002-@ComponentScan、@Autowired的用法

一、ComponentScan 1. Configuration //說明此類是配置文件 ComponentScan //開啟掃描&#xff0c;會掃描當前類的包及其子包 public class CDPlayerConfig { } 2. ComponentScan(basePackages{"soundsystem", "video"})//掃描多個包 public class CDP…

Kurento協議

2019獨角獸企業重金招聘Python工程師標準>>> Kurento媒體服務器可以被兩種外部Kurento客戶端控制&#xff0c;如Java或JavaScript。這些客戶端使用Kuernto協議來和KMS通信。Kurento 協議是基于WebSocket協議&#xff0c;并使用了JSON-RPC V2.0 消息來提交請求和發送…

升級php7_PhpStorm 2019.3 發布,全面支持 PHP 7.4

PhpStorm 2019.3 發布了&#xff0c;這個版本主要集中在性能和質量上&#xff0c;旨在提供一個更穩定、更快的 IDE。PhpStorm 2019.3 全面支持 PHP 7.4&#xff0c;還帶來 PSR-12 代碼樣式&#xff0c;用于遠程解釋器的 WSL&#xff0c;MongoDB 支持&#xff0c;HTTP 客戶端更新…

ftp 客戶端 使用http代理 源碼_代理服務器連接HTTPS過程

說到HTTPS代理很多人瞬間就會聯想到HTTPS的各種證書和各種加密&#xff0c;覺得很高端很復雜的樣子。其實不然&#xff0c;代理服務器不需要配置證書、也不需要處理任何加密。因為HTTPS代理是通過Web隧道(Web tunnel)工作的。Web隧道允許用戶通過HTTP連接發送非HTTP流量(例如FT…

python解zuobiaoxi方程_Python還能解決數學相關問題?大學生:以后就靠他了,事半功倍...

問題背景高等數學應用非常廣&#xff0c;基本上涉及到函數的地方都要用到微積分&#xff0c;還有在幾何方面也是如此&#xff0c;計算機的應用讓我們能簡單快速處理各種高等數學中的計算&#xff0c;比如極限、導數、積分、微分方程等的計算。實驗目的使用 Python 通過計算與作…

Android版:驗證手機號碼的正則表達式 (轉)

/** * 驗證手機格式 */ public static boolean isMobileNO(String mobiles) { /* 移動&#xff1a;134、135、136、137、138、139、150、151、157(TD)、158、159、187、188 聯通&#xff1a;130、131、132、152、155、156、185、186 電信&#xff1a;133、…

基礎正則表達式介紹與練習

基礎正則表達式介紹與練習 一、什么是正則表達式 在做文字處理或編寫程序時&#xff0c;用到查找、替換等功能&#xff0c;使用正則表達式能夠簡單快捷的完成目標。簡單而言&#xff0c;正則表達式通過一些特殊符號的幫助&#xff0c;使用戶可以輕松快捷的完成查找、刪除、替換…

android canvas 網絡圖,【巨坑:toDataURL】canvas合成網絡圖片

不知有沒有小伙伴用過canvas合成圖片&#xff0c;然后爆炸報錯截圖尼瑪&#xff0c;然后各種搜索&#xff0c;不外乎以下幾種坑爹處理方案&#xff1a;后端處理&#xff0c;比如Access-Control-Allow-Origin "*"(要是請求到其他網站的圖片就不適用了&#xff0c;比如…

水晶報表如何查看sql_有了這個報表工具,一鍵生成自定義的各種報表,還可以導出Excel...

EasyReport是一個簡單易用的Web報表工具,它的主要功能是把SQL語句查詢出的數據轉換成報表頁面&#xff0c; 同時支持表格的跨行(RowSpan)與跨列(ColSpan)配置。 同時它還支持報表Excel導出、圖表顯示及固定表頭與左邊列的功能。功能介紹本工具從數據庫(MySQL,Oracle,SQLServer,…

python 三維向量 交互_Blender實現Nature of Code1.5單位向量[Nature of Node 004]

【Nature of Node #004】Blender創意編程進階應用&#xff1a;實現Nature of CodeNature of Code 1.5, Unit Vector (Normalize)背景介紹這個系列“Nature of Node”&#xff0c;是專門用Blender的Node&#xff08;節點&#xff09;方式來實現Nature of Code。用到一個Blender插…

Sitemesh3的使用及配置

1 . Sitemesh 3 簡介 Sitemesh 是一個網頁布局和修飾的框架&#xff0c;基于 Servlet 中的 Filter&#xff0c;類似于 ASP.NET 中的‘母版頁’技術。參考&#xff1a;百度百科&#xff0c;相關類似技術&#xff1a;Apache Tiles。 官網&#xff1a;http://wiki.sitemesh.org/wi…

等保項目流程

等級保護&#xff1a;直屬管理公安局 產品必須通過公安局安全許可證分級保護&#xff1a;直屬管理保密局 產品必須通過保密局銷售許可證等級保護&#xff1a;一般分為5級&#xff0c;目前最高用到是等保4級總概&#xff1a;定級——前期調研——總…

鴻蒙系統r如何升級,高歌猛進,鴻蒙系統升級機型再次確認,花粉:終等到!...

雖然華為手機現在的壓力非常大&#xff0c;但是在前進的道路上&#xff0c;真的充滿了樂觀精神&#xff0c;而且現在也算是一路高歌猛進了&#xff0c;發展路線開始加快了許多&#xff0c;無論是新機還是系統&#xff0c;都有著非常多的新消息。因為華為手機的實力很強&#xf…