最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue解析指令compile源碼層面使用解析

 更新時間:2022年09月16日 10:01:52   作者:super_wanan  
這篇文章主要為大家介紹了Vue編譯器解析compile源碼解析示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

概述

上篇文章我們已經(jīng)介紹了Vue的響應(yīng)式原理,并實現(xiàn)了對數(shù)據(jù)的監(jiān)聽,監(jiān)聽的目的是為了及時更新視圖,所以這篇文章就來介紹下vue解析指令并初始化視圖部分。

compile

在Vue的構(gòu)造函數(shù)中對根元素進(jìn)行編譯

class MVue {
  constructor (options) {
    // 保存options
    this.$options = options
    this.$data = options.data
    // 將data進(jìn)行響應(yīng)式處理
    observe(this.$data)
    // 代理
    proxy(this)
    // 編譯 
    /**核心部分**/
    new Compile(options.el, this)
  }
}
class Compile {
  constructor (el, vm) {
    this.$vm = vm
    this.$el = document.querySelector(el)

    if (this.$el) {
      this.compile(this.$el)
    }
  }
  compile (node) {
    // 找到該元素的子節(jié)點
    const childNodes = node.childNodes
    // childNodes是類數(shù)組對象
    Array.from(childNodes).forEach(n => {
      // 判斷類型
      if (this.isElment(n)) {
        this.compileElement(n)
        // 遞歸
        if (n.childNodes.length > 0) {
          this.compile(n)
        }
      } else if (this.isInter(n)) {
        // 動態(tài)插值表達(dá)式  編譯文本
        this.compileText(n)
      }
    })
  }
  isElment (node) {
    return node.nodeType === 1
  }
  isInter (n) {
    return n.nodeType === 3 && /\{\{(.*)\}\}/.test(n.textContent)
  }
  isDir (attrName) {
    return attrName.startsWith('m-')
  }
  isEvent (attrName) {
    return attrName.startsWith('@')
  }
  // 編譯元素:遍歷它的所有屬性,看是否m-開頭指令,或者@事件
  compileElement (node) {
    const attrs = node.attributes
    Array.from(attrs).forEach(attr => {
      // m-text="XXX"
      // name = m-text, value=xxx
      const attrName = attr.name
      const exp = attr.value
      // 是指令
      if (this.isDir(attrName)) {
        // 執(zhí)行特定指令處理函數(shù)
        const dir = attrName.substring(2)
        this[dir] && this[dir](node, exp)
      } else if (this.isEvent(attrName)) {
      	//是事件
      	const event = attrName.substring(1)
        // 通過bind改變this指向為vm實例,以便方法內(nèi)部訪問vm.data中的數(shù)據(jù)
        node.addEventListener(event, this.$vm.$methods[exp].bind(this.$vm))
      }
    })
  }
  compileText (n) {
    // 獲取表達(dá)式
    // n.textContent = this.$vm[RegExp.$1]
    n.textContent = this.$vm[RegExp.$1.trim()]
  }
  text (node, exp) {
    node.textContent = this.$vm[exp] || exp
  }
  html (node, exp) {
    node.innerHTML = this.$vm[exp]
  }
  model (node, exp) {
    node.value = this.$vm[exp]
  }
}

測試代碼

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div id="app">
        <p>{{ counter }}</p>
        <p m-text="測試"></p>
        <p m-text="counter"></p>
        <p m-html="desc"></p>
        <input m-model="name" />
    </div>
</body>
<script src="./index.js"></script>
<script>
    const app = new MVue({
            el: '#app',
            data: {
                counter: 1,
                desc: '<span style = "color: red">super wanan</span>',
                name: 'wanan'
            }
        })
        // setInterval(() => {
        //     app.counter++
        // }, 1000)
</script>
</html>

結(jié)果

延伸及重點講解

1. 類數(shù)組對象

node.childNodes和node.attributes都是一種類數(shù)組對象,NodeList用于保存一組有序的節(jié)點??梢酝ㄟ^方括號語法來訪問NodeList的值,有item方法與length屬性。它并不是Array的實例,沒有數(shù)組對象的方法。

比如我們再compile方法中打印childNodes,會得到這樣的結(jié)果:

因此需要使用Array.from()方法將類數(shù)組對象轉(zhuǎn)換為真正數(shù)組。

2. RegExp.$1

RegExp 是javascript中的一個內(nèi)置對象。為正則表達(dá)式。

RegExp.$1是RegExp的一個屬性,指的是與正則表達(dá)式匹配的第一個 子匹配(以括號為標(biāo)志)字符串,以此類推,RegExp.$2,RegExp.$3,…RegExp.$99總共可以有99個匹配

其實RegExp這個對象會在我們調(diào)用了正則表達(dá)式的方法后, 自動將最近一次的結(jié)果保存在里面, 所以如果我們在使用正則表達(dá)式時, 有用到分組, 那么就可以直接在調(diào)用完以后直接使用RegExp.$xx來使用捕獲到的分組內(nèi)容。

所以我們在compileText時可以這樣使用:

  compileText (n) {
    // 獲取表達(dá)式
    // n.textContent = this.$vm[RegExp.$1]
    n.textContent = this.$vm[RegExp.$1.trim()]
  }

需要注意的是,上述代碼中還使用了trim方法去除前后空格,這是為了將{{ counter }}前后的空格去掉,正確匹配到this.vm[‘counter’],否則會讀取this.vm[’ counter ']導(dǎo)致讀取不到。

3. nodeType

DOM(文檔對象模型)可以將任何HTML和XML文檔描繪成一個由多層node(節(jié)點)構(gòu)成的結(jié)構(gòu)。

DOM1級定義了一個Node接口,該接口將由DOM中的所有節(jié)點類型實現(xiàn)。這個Node接口在JavaScript中作為Node類型實現(xiàn)的。除了IE之外,在其他所有瀏覽器中都可以訪問到這個類型。JavaScript中的所有節(jié)點類型都繼承自Node類型,因此所有節(jié)點類型都共享相同的基本屬性和方法。每個節(jié)點都有一個nodeType屬性,用于表明節(jié)點的類型。

nodeType的取值如下:

類型nodeType常數(shù)值描述
Node.ELEMENT_NODE1元素節(jié)點
Node.ATTRIBUTE_NODE2屬性節(jié)點
Node.TEXT_NODE3文本節(jié)點
Node.CDATA_SECTION_NODE4字符數(shù)據(jù)節(jié)點(文本不會被解析器解析)
Node.ENTITY_REFERENCE_NODE5實體引用節(jié)點
Node.ENTITY_NODE6實體節(jié)點
Node.PROCESSING_INSTRUCTION_NODE7處理指令節(jié)點
Node.COMMENT_NODE8注釋節(jié)點
Node.DOCUMENT_NODE9文檔節(jié)點(DOM樹的根節(jié)點)
Node.DOCUMENT_TYPE_NODE10向為文檔定義的實體提供接口
Node.DOCUMENT_FRAGMENT_NODE11表示鄰接節(jié)點和它們的子樹
Node.NOTATION_NODE12代表一個符號在DTD中的聲明

到此這篇關(guān)于vue解析指令compile源碼層面使用解析的文章就介紹到這了,更多相關(guān)vue compile內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Vue常用實例方法示例梳理分析

    Vue常用實例方法示例梳理分析

    在了解vue的常用的實例方法之前,我們應(yīng)該先要了解其常用的實例屬性,你能了解到的vue實例屬性有哪些呢?小編在這里就列舉了幾個常用的vue實例的屬性。大家可以一起參考學(xué)習(xí)一下
    2022-08-08
  • vue.js表格組件開發(fā)的實例詳解

    vue.js表格組件開發(fā)的實例詳解

    Vue.js通過簡潔的API提供高效的數(shù)據(jù)綁定和靈活的組件系統(tǒng)。在前端紛繁復(fù)雜的生態(tài)中,Vue.js有幸受到一定程度的關(guān)注,所以本文將從各方面對Vue.js的組件開發(fā)做一個深入介紹。有需要的朋友們可以參考借鑒。
    2016-10-10
  • vue+el-select?多數(shù)據(jù)分頁搜索組件的實現(xiàn)

    vue+el-select?多數(shù)據(jù)分頁搜索組件的實現(xiàn)

    本文主要介紹了vue+el-select?多數(shù)據(jù)分頁搜索組件的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-12-12
  • Vue使用Canvas生成隨機大小且不重疊圓

    Vue使用Canvas生成隨機大小且不重疊圓

    Canvas是HTML5中新增的元素,專門用來繪制圖形,下面這篇文章主要給大家介紹了關(guān)于Vue使用Canvas生成隨機大小且不重疊圓的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2021-11-11
  • Vue中實現(xiàn)視頻播放的示例詳解

    Vue中實現(xiàn)視頻播放的示例詳解

    這篇文章主要為大家學(xué)習(xí)介紹了基于Vue如何實現(xiàn)視頻播放的功能,文中的示例代碼講解詳細(xì),具有一定的參考價值,需要的小伙伴可以了解一下
    2023-08-08
  • vue-cli中的:visible.sync是什么意思

    vue-cli中的:visible.sync是什么意思

    visible前面加冒號的,說明后面是一個變量或者表達(dá)式;沒加冒號的后面就是對應(yīng)的字符串字面量,這篇文章主要介紹了vue-cli中的:visible.sync是什么,需要的朋友可以參考下
    2022-11-11
  • vue+vux?vux安裝出現(xiàn)錯誤問題及解決

    vue+vux?vux安裝出現(xiàn)錯誤問題及解決

    這篇文章主要介紹了vue+vux?vux安裝出現(xiàn)錯誤問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-08-08
  • 基于Vue實現(xiàn)本地消息隊列MQ的示例詳解

    基于Vue實現(xiàn)本地消息隊列MQ的示例詳解

    這篇文章為大家詳細(xì)主要介紹了如何基于Vue實現(xiàn)本地消息隊列MQ, 讓消息延遲消費或者做緩存,文中的示例代碼講解詳細(xì),需要的可以參考一下
    2024-02-02
  • vue+elementUI的select下拉框回顯為數(shù)字問題

    vue+elementUI的select下拉框回顯為數(shù)字問題

    這篇文章主要介紹了vue+elementUI的select下拉框回顯為數(shù)字問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • vue項目無法刪除的問題及解決

    vue項目無法刪除的問題及解決

    這篇文章主要介紹了vue項目無法刪除的問題及解決方案,具有很好的參考價值,希望對的大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-04-04

最新評論

沈丘县| 富源县| 象州县| 汝阳县| 平谷区| 临武县| 张家口市| 民丰县| 阳谷县| 龙井市| 邳州市| 元谋县| 顺义区| 乌鲁木齐县| 佛教| 宁陵县| 惠安县| 扬中市| 南城县| 黎平县| 伽师县| 平安县| 疏勒县| 平度市| 如东县| 沅江市| 西乌珠穆沁旗| 彰化市| 永登县| 拉萨市| 兰西县| 宣化县| 普宁市| 丽水市| 阿拉善左旗| 余干县| 会东县| 万州区| 新竹市| 永济市| 平昌县|