亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專(zhuān)欄INFORMATION COLUMN

手把手教你從零寫(xiě)一個(gè)簡(jiǎn)單的 VUE--模板篇

feng409 / 1202人閱讀

摘要:轉(zhuǎn)換成為模板函數(shù)聯(lián)系上一篇文章,其實(shí)模板函數(shù)的構(gòu)造都大同小異,基本是都是通過(guò)拼接函數(shù)字符串,然后通過(guò)對(duì)象轉(zhuǎn)換成一個(gè)函數(shù),變成一個(gè)函數(shù)之后,只要傳入對(duì)應(yīng)的數(shù)據(jù),函數(shù)就會(huì)返回一個(gè)模板數(shù)據(jù)渲染好的字符串。

教程目錄
1.手把手教你從零寫(xiě)一個(gè)簡(jiǎn)單的 VUE
2.手把手教你從零寫(xiě)一個(gè)簡(jiǎn)單的 VUE--模板篇

Hello,我又回來(lái)了,上一次的文章教會(huì)了大家如何書(shū)寫(xiě)一個(gè)簡(jiǎn)單 VUE,里面實(shí)現(xiàn)了VUE 的數(shù)據(jù)驅(qū)動(dòng)視圖渲染模板,更新到頁(yè)面的過(guò)程,簡(jiǎn)單的帶大家了解了類(lèi)似 VUE 這樣子的數(shù)據(jù)驅(qū)動(dòng)視圖框架的工作流程,今天我來(lái)給大家講一講作為一個(gè)前端框架最為核心的部分---模板,代碼還是放在文章的最后,請(qǐng)隨意下載

模板的分類(lèi)

在介紹我們實(shí)現(xiàn)的模板語(yǔ)言之前,我們先來(lái)了解下,現(xiàn)在市面上比較流行的模板語(yǔ)言:

PHP/ASP/JSP風(fēng)格
   <%if(list.length ){%>   
    <%for(n = 0; n < list.length; ++n ){%>
  1. <%=list[n]%>
  2. <%}%>
<%}%>

這種是最接近于 js 變成語(yǔ)言的語(yǔ)法,比較直觀,但是由于存在< >的分隔符,對(duì) IDE不太友好,不太好進(jìn)行格式化處理

mustcache風(fēng)格
    {{#if list.length}}  
    
    {{#each list item}}
  1. {{item}}
  2. {{/each}}
{{/if}}

這種是artTemplate默認(rèn)的語(yǔ)法,高級(jí)語(yǔ)法有限,通常難自定義拓展

DSL風(fēng)格語(yǔ)法
 

首先介紹下什么是DSL, DSL全稱(chēng)是Domain Specific Language/DSL領(lǐng)域?qū)S谜Z(yǔ)言,其基本思想是求專(zhuān)不求全,用于解決一個(gè)類(lèi)型,一個(gè)領(lǐng)域的問(wèn)題。比如Vue里面的v-xxx,Vue稱(chēng)之為指令,其實(shí)就是一個(gè)DSL,用于解決模板語(yǔ)法等問(wèn)題,這種模板由于在html語(yǔ)法里面相當(dāng)于標(biāo)簽的屬性,所以對(duì)IDE友好,不會(huì)影響格式化操作。

Vue的模板語(yǔ)法相當(dāng)于結(jié)合了 DSL語(yǔ)法和 mustcache風(fēng)格, 邏輯控制部分使用DSL語(yǔ)法,輸出展示部分使用 mustcache風(fēng)格

模板引擎設(shè)計(jì)思路

下面是這個(gè)模板引擎的思路:

字符串模板語(yǔ)法定義

首先我們要定義一種模板語(yǔ)法,按照上一節(jié)的說(shuō)明,我們使用DSL風(fēng)格語(yǔ)法,下面是我們測(cè)試用的模板

我們采用最簡(jiǎn)單的將模板寫(xiě)在script標(biāo)簽的配置方式,可以看到我們定義了幾個(gè)DSL,分別是dsl-if,dsl-for,dsl-html,分別用于判斷,循環(huán)和直接輸出 html,還有使用mustcache作為字符串輸出語(yǔ)法。當(dāng)然這個(gè)只是一個(gè)簡(jiǎn)單的模板DSL語(yǔ)言,主要為了講解思路,真正的模板需要更加多的模板語(yǔ)法,具體可以參照 VUE文檔

模板解析成為 AST

首先解釋下什么是AST,AST 全稱(chēng)為abstract syntax tree(抽象語(yǔ)法樹(shù)),是源代碼的抽象語(yǔ)法結(jié)構(gòu)的樹(shù)狀表現(xiàn)形式,每種源碼都可以被抽象成為AST,比如我們常用的 js,css,json 等,都可以解析成為 AST
把模板解析成為AST,就是將模板的 html 結(jié)構(gòu)進(jìn)行解析,變成一顆附帶結(jié)構(gòu)、關(guān)系、屬性的抽象樹(shù),這樣做方便與后面我們多次對(duì)模板進(jìn)行處理,減少了多次解析字符串帶來(lái)的損耗,同時(shí)變成一顆樹(shù)的數(shù)據(jù)結(jié)構(gòu)之后更加方便于我們的遍歷,關(guān)于AST的優(yōu)點(diǎn)缺點(diǎn)大家可以執(zhí)行搜索,這里就不展開(kāi)說(shuō)明了
上面的字符串模板解析完成之后,會(huì)變成以下的一個(gè)AST

可以看到字符串模板變成了一個(gè)object數(shù)組,每個(gè) obj 代表一個(gè)節(jié)點(diǎn),里面包含了這個(gè) obj 的屬性,類(lèi)型,父子關(guān)系,用到的DSL等等。這個(gè)可以看成是我們的模板的一個(gè)中間態(tài),為我們進(jìn)行進(jìn)一步處理打下了基礎(chǔ)。

AST 轉(zhuǎn)換成為 模板函數(shù)

聯(lián)系上一篇文章,其實(shí)模板函數(shù)的構(gòu)造都大同小異,基本是都是通過(guò)拼接函數(shù)字符串,然后通過(guò)Function對(duì)象轉(zhuǎn)換成一個(gè)函數(shù),變成一個(gè)函數(shù)之后,只要傳入對(duì)應(yīng)的數(shù)據(jù),函數(shù)就會(huì)返回一個(gè)模板數(shù)據(jù)渲染好的 html 字符串。下面是例子中通過(guò)AST

這是個(gè)函數(shù)體,然后使用new Function,就變成一個(gè)真正的函數(shù)了,至于這個(gè)函數(shù)體的解釋?zhuān)覍⒎旁谙旅婢唧w實(shí)現(xiàn)進(jìn)行講解

數(shù)據(jù)與模板函數(shù)結(jié)合生成 html

由于本文主要是講模板的實(shí)現(xiàn),因此數(shù)據(jù)部分還是使用延續(xù)上一篇文章的綁定,在初始化或者數(shù)據(jù)發(fā)生改變的時(shí)候,響應(yīng)的函數(shù)會(huì)對(duì)數(shù)據(jù)所關(guān)聯(lián)的模板函數(shù)進(jìn)行重新調(diào)用,生成新的html,重新進(jìn)行渲染。

模板的開(kāi)發(fā)思路我們就在上面都說(shuō)明了,主要總結(jié)下就是將字符串模板變成 ast,ast 變成模板函數(shù),然后就可以結(jié)合數(shù)據(jù)進(jìn)行 html 生成及渲染了

具體實(shí)現(xiàn)方法

首先說(shuō)明下本教程的方法是對(duì)思路的實(shí)現(xiàn),并非完全使用 vue 的實(shí)現(xiàn)方法,vue 是一個(gè)完整的框架,里面涉及的東西比較多,我們的實(shí)現(xiàn)是為了讓大家更好的了解 vue 的原理,而非完全實(shí)現(xiàn)

字符串模板變成AST部分

1.模板預(yù)處理:
由于字符串模板是人為處理的,因此書(shū)寫(xiě)的時(shí)候可能會(huì)出現(xiàn)標(biāo)簽不配對(duì),標(biāo)簽未關(guān)閉等問(wèn)題,因此我們要先做些預(yù)處理,來(lái)去除這些干擾,做法有很多種,比如通過(guò)一些語(yǔ)法分析的工具進(jìn)行解析,這里我們使用一種比較簡(jiǎn)單的方式進(jìn)行處理,代碼如下(/src/core/render.js):

可以看到我創(chuàng)建了一個(gè)div標(biāo)簽,然后將字符串模板放進(jìn)去里面,這樣子瀏覽器會(huì)對(duì)模板進(jìn)行解析處理,然后我們?cè)偻ㄟ^(guò)innerHTML去除前后空格之后拿出來(lái),這樣就對(duì)字符串模板進(jìn)行了處理。
備注:我們按照 vue 的規(guī)則,一個(gè)模板只有一個(gè)根節(jié)點(diǎn),所以我們?nèi)×?b>childNodes[0]

2.生成 ast:
上面我們對(duì)字符串模板進(jìn)行了預(yù)處理,接下去我們要將字符串模板轉(zhuǎn)換成ast,代碼比較長(zhǎng),大家有興趣可以看下/src/compiler/ast/parse.js,下面說(shuō)下解析思路
解析通過(guò)正則表達(dá)式配合 String.replace(regExt,fn),正則表達(dá)式為/<(?:"[^"]*"[""]*|"[^"]*"[""]*|[^"">])+>/g,解析出來(lái)標(biāo)簽和標(biāo)簽上面的屬性,然后按照需求進(jìn)行存儲(chǔ),就生成 ast

ast 生成模板函數(shù)

生成模板函數(shù)的思路就是遞歸遍歷ast 樹(shù),對(duì)不同的類(lèi)型節(jié)點(diǎn),不同的NSL,調(diào)用不同的生成函數(shù),最后組合成為模板函數(shù)字符串,代碼如下(/src/compiler/compiler-helper.js):

可以看到,處理的函數(shù)對(duì) DSL還有不同的標(biāo)簽類(lèi)型進(jìn)行處理,然后都返回了一個(gè)輔助函數(shù)的調(diào)用,比如_i,_f,_c等等,這里的輔助函數(shù)是在模板函數(shù)被調(diào)用的時(shí)候才真正的被調(diào)用的,下面我們舉例說(shuō)明一個(gè)輔助函數(shù)_c

這個(gè)輔助函數(shù)的功能是用于生成節(jié)點(diǎn),可以看到調(diào)用了這個(gè)函數(shù)之后,對(duì)應(yīng)的 ast 里面的節(jié)點(diǎn)被真正生成,變成dom節(jié)點(diǎn),并且會(huì)把孩子節(jié)點(diǎn)進(jìn)行插入,通過(guò)很多輔助函數(shù)的遞歸嵌套調(diào)用,最終模板函數(shù)一調(diào)用,就可以結(jié)合數(shù)據(jù)渲染出來(lái)真實(shí)的dom節(jié)點(diǎn)

下面說(shuō)一個(gè)比較細(xì)的知識(shí)點(diǎn),就是輔助函數(shù)的調(diào)用,我們知道上面的輔助函數(shù)調(diào)用在生成的時(shí)候,其實(shí)都是字符串,然后通過(guò)new Function讓他變成真正的函數(shù),那么問(wèn)題就來(lái)了,我們知道new Function是的作用域和運(yùn)行時(shí)的代碼是隔離的,是調(diào)用不到外面的_c,_f等輔助函數(shù)的,那是如何實(shí)現(xiàn)調(diào)用的呢,這里用了一個(gè)我們很少使用的關(guān)鍵字with,這個(gè)關(guān)鍵字在很多書(shū)籍里面都不推薦使用,因?yàn)樗淖饔檬切薷?b>with包含代碼塊的作用域,如果濫用會(huì)導(dǎo)致代碼的邏輯不可控,但是在模板函數(shù)里面這個(gè)關(guān)鍵字有奇效,他可以方便的規(guī)定把當(dāng)前的代碼作用域傳到模板函數(shù)里面,從而使得模板函數(shù)里面可以調(diào)用到運(yùn)行時(shí)作用域的函數(shù)。大家可以看下上一小節(jié)生成的模板函數(shù)字符串,會(huì)發(fā)現(xiàn)就是用整個(gè)with(that){}包裹起來(lái)的,在模板函數(shù)運(yùn)行時(shí),將當(dāng)前作用域直接傳入即可,代碼如下:

結(jié)合數(shù)據(jù)運(yùn)行

至此,我們已經(jīng)生成了模板函數(shù),通過(guò)傳入數(shù)據(jù)運(yùn)行模板函數(shù),就可以生成 dom,代碼如下:

可以我們直接把compiler_helper附帶上 data 作為作用域,直接調(diào)用了模板函數(shù),就可以生成dom,再結(jié)合我們第一篇文章寫(xiě)的數(shù)據(jù)監(jiān)聽(tīng),就可以實(shí)現(xiàn)簡(jiǎn)單的數(shù)據(jù)驅(qū)動(dòng)視圖

后話(huà)

至此,我們的VUE模板的基本實(shí)現(xiàn)已經(jīng)介紹完成了,這里主要是介紹如何去實(shí)現(xiàn)一個(gè)模板引擎的思路,所以功能上上面的實(shí)現(xiàn)不是完整的,只是實(shí)現(xiàn)了一些簡(jiǎn)單的語(yǔ)法,大家可以下下代碼繼續(xù)補(bǔ)充。

思考

細(xì)心的人可能會(huì)發(fā)現(xiàn),我們上面的模板有個(gè)問(wèn)題,就是如果改了數(shù)據(jù)中的其中一個(gè)數(shù)值,那么整個(gè)模板都得重新編譯,重新渲染,這其實(shí)是非常損耗性能的,這其實(shí)就是我下一篇文章要講的,模板渲染的效率問(wèn)題,先提出幾個(gè)關(guān)鍵詞 虛擬dom,diff 算法,最小化渲染,吊吊大家的胃口,哈哈,下一篇文章我會(huì)進(jìn)行全面的介紹,相信學(xué)習(xí)完下一篇文章,大家會(huì)對(duì)現(xiàn)有市面上的數(shù)據(jù)驅(qū)動(dòng)框架的模板部分有個(gè)全面的了解~下一篇文章更加精彩哦~~求關(guān)注
最后附上源碼點(diǎn)我點(diǎn)我,各位客官給個(gè) star 唄~~

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/87215.html

相關(guān)文章

  • 把手教你零寫(xiě)一個(gè)簡(jiǎn)單 VUE

    摘要:本系列是一個(gè)教程,下面貼下目錄手把手教你從零寫(xiě)一個(gè)簡(jiǎn)單的手把手教你從零寫(xiě)一個(gè)簡(jiǎn)單的模板篇今天給大家?guī)?lái)的是實(shí)現(xiàn)一個(gè)簡(jiǎn)單的類(lèi)似一樣的前端框架,框架現(xiàn)在應(yīng)該算是非常主流的前端數(shù)據(jù)驅(qū)動(dòng)框架,今天我們來(lái)從零開(kāi)始寫(xiě)一個(gè)非常簡(jiǎn)單的框架,主要是讓大家 本系列是一個(gè)教程,下面貼下目錄~1.手把手教你從零寫(xiě)一個(gè)簡(jiǎn)單的 VUE2.手把手教你從零寫(xiě)一個(gè)簡(jiǎn)單的 VUE--模板篇 今天給大家?guī)?lái)的是實(shí)現(xiàn)一個(gè)簡(jiǎn)單...

    RebeccaZhong 評(píng)論0 收藏0
  • 2017-06-20 前端日?qǐng)?bào)

    摘要:前端日?qǐng)?bào)精選專(zhuān)題之跟著學(xué)節(jié)流冴羽的博客全家桶仿微信項(xiàng)目,支持多人在線(xiàn)聊天和機(jī)器人聊天騰訊前端團(tuán)隊(duì)社區(qū)編碼的奧秘模塊實(shí)現(xiàn)入門(mén)淺析知乎專(zhuān)欄前端每周清單發(fā)布新版本提升應(yīng)用性能的方法中文寇可往吾亦可往用實(shí)現(xiàn)對(duì)決支付寶的微信企業(yè)付款到零 2017-06-20 前端日?qǐng)?bào) 精選 JavaScript專(zhuān)題之跟著 underscore 學(xué)節(jié)流 - 冴羽的JavaScript博客 - SegmentFau...

    Galence 評(píng)論0 收藏0
  • 把手教你從零搭建react局部熱加載環(huán)境

    摘要:有沒(méi)有辦法實(shí)現(xiàn)就局部刷新呢當(dāng)然是有第十步執(zhí)行為了實(shí)現(xiàn)局部熱加載,我們需要添加插件。 前言 用了3個(gè)多月的vue自認(rèn)為已經(jīng)是一名合格的vue框架api搬運(yùn)工,對(duì)于vue的api使用到達(dá)了一定瓶頸,無(wú)奈水平有限,每每深入底層觀賞源碼時(shí)候都迷失了自己。 遂決定再找個(gè)框架學(xué)習(xí)學(xué)習(xí)看看能否突破思維局限,加上本人早已對(duì)React、RN技術(shù)垂涎已久,于是決定找找教程來(lái)學(xué)習(xí)。無(wú)奈第一步就卡在了環(huán)境搭...

    quietin 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

feng409

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<