打造屬于自己的MVVM框架: 2.模版渲染引擎

上一篇介紹了MVVM的基本知識(shí),本篇講針對(duì)MVVM的模版渲染引擎進(jìn)行介紹灵汪,不但從原理上對(duì)模版引擎的渲染原理進(jìn)行剖析败许,而且有會(huì)相應(yīng)的實(shí)現(xiàn)代碼。

源碼請(qǐng)戳
原文請(qǐng)戳

什么是模版渲染引擎

還是先來看一下上一篇有關(guān)knockoutjs的Demo:

<p>First name: <strong data-bind="text: firstName"></strong></p>
<p>Last name: <strong data-bind="text: lastName"></strong></p>
var viewModel = {
    firstName: "Bert",
    lastName: "Bertington"
};
ko.applyBindings(viewModel);

頁面效果:

First name: Bert

Last name: Bertington

在HTML里砰嘁,我們用data-bind: "text: firstName"作為Binding Instruction,而在JS里的viewModel相當(dāng)于一個(gè)$scope,當(dāng)Dom加載時(shí)件炉,首先會(huì)檢查HTML標(biāo)簽,發(fā)現(xiàn)有Binding Instruction后會(huì)對(duì)DOM進(jìn)行解析般码,此時(shí)根據(jù)具體的指令在viewModel中進(jìn)行解析妻率,將解析后的值渲染到已經(jīng)生成的DOM樹上,就完成了整個(gè)指令渲染工作板祝,而這個(gè)流程宫静,就是前端模版渲染引擎的主要任務(wù)。

怎么做一個(gè)簡單的渲染引擎

其實(shí)稱為引擎還真有點(diǎn)夸張,充其量它只不過是一個(gè)解析的邏輯流程孤里,在整個(gè)過程中有三個(gè)部分:

  • 模版伏伯,即Html
  • 渲染源,即viewModel
  • 所謂的引擎捌袜,一段解析流程的说搅,由knockoutjs負(fù)責(zé)

現(xiàn)在我們來自己試著實(shí)現(xiàn)一下這個(gè)模版引擎。

1.模版

為了在渲染是保留原模版虏等,我采用template標(biāo)簽去畫Html模版弄唧,因?yàn)椋?/p>

  • template標(biāo)簽可以放在任意位置
  • template標(biāo)簽?zāi)J(rèn)display: none

基于以上優(yōu)點(diǎn),個(gè)人覺得template標(biāo)簽太適合做模版了霍衫,難怪會(huì)稱為template候引。

<template id="test">
    <p>First name: <strong data-bind="text: firstName"></strong></p>
    <p>Last name: <strong data-bind="text: lastName"></strong></p>
</template>

將我們要渲染的Html包裹在<template>中,加上id是為了能夠確保唯一敦跌。

2.解析template

利用id我們可以唯一找到template澄干,首先將template里的內(nèi)容取出來,

var clone = document.importNode(document.querySelector('#' + id).content, true);

分離子節(jié)點(diǎn)

var fragmentContent = splitSubRealDoms(clone);
function splitSubRealDoms(fatherDom) {
    var subRealDoms = [];
    while(fatherDom.firstElementChild) {
        var firstElementChild = fatherDom.removeChild(fatherDom.firstElementChild);
        subRealDoms.push(firstElementChild);
    }
    return subRealDoms;
}

3.根據(jù)父節(jié)點(diǎn)的Binding Instruction去渲染子節(jié)點(diǎn)

for(var i = 0;i < fragmentContent.length;i++) {
    var result = renderTemplate(fragmentContent[i], viewModel);
}

renderTemplate的方法較為復(fù)雜柠傍,首先會(huì)渲染父節(jié)點(diǎn)麸俘,然后將所有的子節(jié)點(diǎn)當(dāng)作父節(jié)點(diǎn)再次遞歸,直到?jīng)]有子節(jié)點(diǎn)為止惧笛。遞歸后的子節(jié)點(diǎn)集合渲染完后从媚,需要加入到重新加入到父節(jié)點(diǎn)中。遞歸中途需要對(duì)data-bind = instruction: value進(jìn)行解析徐紧,將得到的value值在viewModel的$scope中静檬,利用eval進(jìn)行解析后綁定到DOM上。(詳細(xì)代碼略長并级,就不在這里貼了拂檩,可以去我的repo里去查看)

4.渲染完成

渲染完成后,將最終的結(jié)果插入到body上嘲碧。

    $('body').append($(result));

5.總結(jié)

這一節(jié)主要介紹了前端模版引擎的工作原理稻励,同時(shí)也分享了我自己的代碼。但模版引擎僅僅只起到了單向綁定的效果(即viewModl->view)愈涩,要想體現(xiàn)MVVM的優(yōu)勢望抽,那就必須得實(shí)現(xiàn)雙向綁定,那就必須的介紹MVVM中的核心對(duì)象observable了履婉,下一篇會(huì)介紹如何實(shí)現(xiàn)observable煤篙。

源碼請(qǐng)戳
原文請(qǐng)戳

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市毁腿,隨后出現(xiàn)的幾起案子辑奈,更是在濱河造成了極大的恐慌苛茂,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件鸠窗,死亡現(xiàn)場離奇詭異妓羊,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)稍计,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門躁绸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人臣嚣,你說我怎么就攤上這事净刮。” “怎么了茧球?”我有些...
    開封第一講書人閱讀 156,852評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵庭瑰,是天一觀的道長。 經(jīng)常有香客問我抢埋,道長,這世上最難降的妖魔是什么督暂? 我笑而不...
    開封第一講書人閱讀 56,408評(píng)論 1 283
  • 正文 為了忘掉前任揪垄,我火速辦了婚禮,結(jié)果婚禮上逻翁,老公的妹妹穿的比我還像新娘饥努。我一直安慰自己,他們只是感情好八回,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,445評(píng)論 5 384
  • 文/花漫 我一把揭開白布酷愧。 她就那樣靜靜地躺著,像睡著了一般缠诅。 火紅的嫁衣襯著肌膚如雪溶浴。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,772評(píng)論 1 290
  • 那天管引,我揣著相機(jī)與錄音士败,去河邊找鬼。 笑死褥伴,一個(gè)胖子當(dāng)著我的面吹牛谅将,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播重慢,決...
    沈念sama閱讀 38,921評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼饥臂,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了似踱?” 一聲冷哼從身側(cè)響起隅熙,我...
    開封第一講書人閱讀 37,688評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤稽煤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后猛们,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體念脯,經(jīng)...
    沈念sama閱讀 44,130評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,467評(píng)論 2 325
  • 正文 我和宋清朗相戀三年弯淘,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了绿店。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,617評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡庐橙,死狀恐怖假勿,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情态鳖,我是刑警寧澤转培,帶...
    沈念sama閱讀 34,276評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站浆竭,受9級(jí)特大地震影響浸须,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜邦泄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,882評(píng)論 3 312
  • 文/蒙蒙 一删窒、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧顺囊,春花似錦肌索、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至午乓,卻和暖如春站宗,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背硅瞧。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評(píng)論 1 265
  • 我被黑心中介騙來泰國打工份乒, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人腕唧。 一個(gè)月前我還...
    沈念sama閱讀 46,315評(píng)論 2 360
  • 正文 我出身青樓茵汰,卻偏偏與公主長得像琳拭,于是被迫代替她去往敵國和親尺铣。 傳聞我的和親對(duì)象是個(gè)殘疾皇子硕旗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,486評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • 這篇筆記主要包含 Vue 2 不同于 Vue 1 或者特有的內(nèi)容,還有我對(duì)于 Vue 1.0 印象不深的內(nèi)容但惶。關(guān)于...
    云之外閱讀 5,046評(píng)論 0 29
  • MVVM(Model View ViewModel)是一種基于MVC的設(shè)計(jì)耳鸯,開發(fā)人員在HTML上寫一些Bindin...
    Pursue閱讀 3,086評(píng)論 0 10
  • MVVM中對(duì)Bingding的解析只能算viewModel->view的單項(xiàng)綁定湿蛔,但MVVM絕不僅僅只有單向綁定,...
    Pursue閱讀 715評(píng)論 4 6
  • 每天一百多人的門診工作量县爬,對(duì)于出門診的醫(yī)生就是折磨阳啥,看病要麻利,詢問病史要簡要擊中要害财喳,不讓病人集堆察迟,下班時(shí)...
    慈桉閱讀 373評(píng)論 0 1
  • 看清自己的我,很悲傷…… 在別人感情世界里面指點(diǎn)耳高、談?wù)撛浚e聊的我,一個(gè)人的時(shí)候泌枪,充滿了落寞....
    堂堂工閱讀 139評(píng)論 0 0