摘要:原文地址一個(gè)框架一個(gè)響應(yīng)式的組件系統(tǒng),通過(guò)把頁(yè)面抽象成一個(gè)個(gè)組件來(lái)增加復(fù)用性降低復(fù)雜性主要特色就是數(shù)據(jù)操縱視圖變化,一旦數(shù)據(jù)變化自動(dòng)更新所有關(guān)聯(lián)組件所以它的一大特性就是一個(gè)數(shù)據(jù)響應(yīng)系統(tǒng),當(dāng)然有了數(shù)據(jù)還需要一個(gè)模板解析系統(tǒng)即幫我們把數(shù)據(jù)模板生
原文地址:https://gmiam.com/post/evo.html
Vue 一個(gè) MVVM 框架、一個(gè)響應(yīng)式的組件系統(tǒng),通過(guò)把頁(yè)面抽象成一個(gè)個(gè)組件來(lái)增加復(fù)用性、降低復(fù)雜性
主要特色就是數(shù)據(jù)操縱視圖變化,一旦數(shù)據(jù)變化自動(dòng)更新所有關(guān)聯(lián)組件~
所以它的一大特性就是一個(gè)數(shù)據(jù)響應(yīng)系統(tǒng),當(dāng)然有了數(shù)據(jù)還需要一個(gè)模板解析系統(tǒng)
即 HTMLParse 幫我們把數(shù)據(jù)模板生成最終的頁(yè)面,但每次數(shù)據(jù)變動(dòng)都重新生成 HTML 片段掛載到 DOM 性能肯定慢的沒(méi)法說(shuō)
所以還需要 Virtual DOM 把最少的變動(dòng)應(yīng)用到 DOM 上,以提升性能
基本上述三項(xiàng)組裝到一起也就出來(lái)了我們自己的 Vue 框架 Evo
下面先介紹下 Virtual DOM
所謂的 Virtual DOM 就是用 JS 來(lái)模擬 DOM 樹(shù)(因?yàn)?JS 操作比 DOM 快很多)
每次數(shù)據(jù)變動(dòng)用新生成的樹(shù)與之前的樹(shù)做比對(duì),計(jì)算出最終的差異補(bǔ)丁到真正的 DOM 樹(shù)上
Vue 2.0 底層基于 Snabbdom 這個(gè) Virtual DOM 做了優(yōu)化與整合
具體可以到這里查看更多 https://github.com/snabbdom/s...
這個(gè)庫(kù)的主要特色是簡(jiǎn)單、模塊化方便擴(kuò)展與出色的性能
一個(gè)簡(jiǎn)單例子
var snabbdom = require("snabbdom"); var patch = snabbdom.init([ // Init patch function with chosen modules require("snabbdom/modules/class").default, // makes it easy to toggle classes require("snabbdom/modules/props").default, // for setting properties on DOM elements require("snabbdom/modules/style").default, // handles styling on elements with support for animations require("snabbdom/modules/eventlisteners").default, // attaches event listeners ]); var h = require("snabbdom/h").default; // helper function for creating vnodes var container = document.getElementById("container"); var vnode = h("div#container.two.classes", {on: {click: someFn}}, [ h("span", {style: {fontWeight: "bold"}}, "This is bold"), " and this is just normal text", h("a", {props: {href: "/foo"}}, "I"ll take you places!") ]); // Patch into empty DOM element – this modifies the DOM as a side effect patch(container, vnode); var newVnode = h("div#container.two.classes", {on: {click: anotherEventHandler}}, [ h("span", {style: {fontWeight: "normal", fontStyle: "italic"}}, "This is now italic type"), " and this is still just normal text", h("a", {props: {href: "/bar"}}, "I"ll take you places!") ]); // Second `patch` invocation patch(vnode, newVnode); // Snabbdom efficiently updates the old view to the new state
不難看出 patch 就是一個(gè)模塊化的功能聚合,你也可以根據(jù)核心的 Hook 機(jī)制來(lái)提供自己的功能模塊
然后通過(guò) snabbdom/h 來(lái)創(chuàng)建 vnodes,最后用 patch 做更新處理
這個(gè)庫(kù)的代碼量不大,實(shí)現(xiàn)的非常靈活,有興趣的可以讀讀源碼,另外也建議讀讀這篇文章 https://github.com/livoras/bl... 以更好的了解內(nèi)部原理
不過(guò)從上面的語(yǔ)法可以看出使用起來(lái)相當(dāng)麻煩,所以我們需要一種簡(jiǎn)單的書(shū)寫(xiě)方式來(lái)幫我們解析成對(duì)應(yīng)的語(yǔ)法規(guī)則
也就是要說(shuō)的 HTMLParse
Vue 2.0 的 Parse 原型基于 John Resig 的 HTML Parser,這個(gè) Parser 寫(xiě)的很小巧,可以到這里了解 http://ejohn.org/blog/pure-ja...
基本的 HTML 解析用法
var results = ""; HTMLParser(html, { start: function( tag, attrs, unary ) { results += "<" + tag; for ( var i = 0; i < attrs.length; i++ ) results += " " + attrs[i].name + "="" + attrs[i].escaped + """; results += (unary ? "/" : "") + ">"; }, end: function( tag ) { results += "" + tag + ">"; }, chars: function( text ) { results += text; }, comment: function( text ) { results += ""; } }); return results;
可以看出它把 HTML 解析后對(duì)應(yīng)的節(jié)點(diǎn)數(shù)據(jù)都傳入了處理函數(shù),Vue 在它的基礎(chǔ)上做了升級(jí)與優(yōu)化處理,在拿到對(duì)應(yīng)的節(jié)點(diǎn)數(shù)據(jù)后做一些自己的解析處理,如 分析 v-if、v-for、v-on 等屬性做指令處理,也就出來(lái)了 Vue 的模板系統(tǒng)~
下面在說(shuō)下響應(yīng)系統(tǒng)
數(shù)據(jù)響應(yīng)主要是依據(jù) ES5 的 getter 與 setter 來(lái)做數(shù)據(jù)變化的鉤子處理,比如下面
Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: ()=>{ // some handle return val }, set: newVal => { if(newVal === val) return val = newVal //some handle } })
這樣取值與賦值的過(guò)程中都可以做一些我們自己的處理,比如 set 的時(shí)候我們可以判斷值是否真的發(fā)生了變化,變化了可以觸發(fā)我們的重新渲染函數(shù),做虛擬 DOM 比對(duì)處理更新界面
不過(guò)說(shuō)明下并不是一旦有數(shù)據(jù)變動(dòng)我們就要做重新渲染,看這個(gè)例子
new Vue({ template: `name: {{name}} age: {{age}} `, data: { name: "js", age: 24, height: 180 } }) setTimeout(function(){ demo.height = 181 }, 3000)可以看到 height 的變動(dòng)與我們的模板完全無(wú)關(guān),如果做重渲染會(huì)造成浪費(fèi),所以 Vue 做了一個(gè)收集依賴
Vue 在第一次渲染的時(shí)候會(huì)讀取需要的數(shù)據(jù),所以它在 get 的時(shí)候做了手腳(依賴收集),后面只有依賴的數(shù)據(jù)變動(dòng)才會(huì)觸發(fā)重渲染
想更詳細(xì)的了解數(shù)據(jù)響應(yīng)的可以看看這個(gè) https://segmentfault.com/a/11...
不過(guò) ES5 的 setter、getter,使用與處理起來(lái)還是有些麻煩與不便
所以數(shù)據(jù)方面我選擇了這個(gè) https://github.com/nx-js/obse... 使用 Proxy 的庫(kù)做響應(yīng)處理(畢竟現(xiàn)在不考慮兼容性~)
實(shí)現(xiàn)原理與上面的差不多,只不過(guò)更簡(jiǎn)單,功能更強(qiáng)一些~
上面就是我們主要參考的技能點(diǎn),讓我們加些代碼把它們連起來(lái),這樣自己的框架就出來(lái)了~
最終的實(shí)現(xiàn)代碼在這里 https://github.com/ygm125/evo
evo = easy + vue + o,快來(lái)幫我 star 吧~
下面來(lái)個(gè)例子,跑起來(lái)
當(dāng)然實(shí)現(xiàn)一個(gè)完整的東西還是有很多路要走的,希望大家都能越走越遠(yuǎn),也能越走越近~
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/81314.html
相關(guān)文章
Vue核心50講 | 第一回:Vue 與 MVVM 之間那些事兒
摘要:在說(shuō)真正的內(nèi)容之前,咱們還要先來(lái)說(shuō)說(shuō)與之間的那些事兒。的核心庫(kù)只關(guān)注視圖層,不僅易于上手,還便于與第三方庫(kù)或既有項(xiàng)目整合。高效核心庫(kù)文件壓縮之后只有,遠(yuǎn)比的壓縮版文件小得多。這么說(shuō)還是會(huì)比較抽象,接下來(lái)咱們用代碼來(lái)進(jìn)一步解釋和之間的關(guān)系。 書(shū)接上文,上一回咱們說(shuō)到了如今的前端江湖早已是框架三分天下的格局。接下來(lái),咱們就要說(shuō)到主角 Vue 了。在說(shuō)真正的 Vue 內(nèi)容之前,咱們還要先來(lái)說(shuō)...
介紹一項(xiàng)讓 React 可以與 Vue 抗衡的技術(shù)
摘要:明明如日中天,把它與倒過(guò)來(lái),給加點(diǎn)東西或可與抗衡。在之后,大版本有十?dāng)?shù)個(gè),只有最近推的才回歸正常等后人總結(jié)歷史,無(wú)疑會(huì)把與之間的所有都稱為垃圾。讓網(wǎng)頁(yè)支持所見(jiàn)即得的可視化設(shè)計(jì),是框架的最高形態(tài),以前沒(méi)有類似工具,主要因?yàn)榧夹g(shù)做不到。 好吧,我承認(rèn)我是標(biāo)題黨。React 明明如日中天,把它與 Vue 倒過(guò)來(lái),給 Vue 加點(diǎn)東西或可與 React 抗衡。不過(guò),這兩年 Vue 干的正是這事...
基于Vue的MVVM學(xué)習(xí)筆記
摘要:發(fā)布訂閱現(xiàn)在每個(gè)人應(yīng)該都用微信吧,一個(gè)人可以關(guān)注多個(gè)公眾號(hào),多個(gè)人可以同時(shí)關(guān)注相同的公眾號(hào)。公眾號(hào)每周都會(huì)更新內(nèi)容,并推送給我們,把寫(xiě)好的文章在微信管理平臺(tái)更新就好了,點(diǎn)擊推送,就相當(dāng)于發(fā)布。 什么是MVVM MVVM——Model-View-ViewModle的縮寫(xiě),MVC設(shè)計(jì)模式的改進(jìn)版。Model是我們應(yīng)用中的數(shù)據(jù)模型,View是我們的UI層,通過(guò)ViewModle,可以把我們M...
發(fā)表評(píng)論
0條評(píng)論
閱讀 3282·2021-10-11 10:59
閱讀 2848·2021-10-11 10:58
閱讀 2260·2021-09-04 16:45
閱讀 2737·2019-08-30 15:44
閱讀 688·2019-08-30 15:44
閱讀 3211·2019-08-30 10:51
閱讀 1608·2019-08-29 18:46
閱讀 2768·2019-08-29 13:57