vue查找指令和模板思路詳解
本文要實(shí)現(xiàn)的是查找指令和模板。
大致的思路是這樣的:
- 遍歷所有的節(jié)點(diǎn)
- 需要判斷當(dāng)前遍歷到的節(jié)點(diǎn)是一個(gè)元素還是一個(gè)文本
- 如果是一個(gè)元素, 我們需要判斷有沒有v-model屬性
- 如果是一個(gè)文本, 我們需要判斷有沒有{{}}的內(nèi)容
那么隨著思路的展開,接下來我們就來實(shí)現(xiàn)這個(gè)功能。
首先我們編寫一個(gè) buildTemplate 方法,主要功能是利用指定的數(shù)據(jù)編譯內(nèi)存中的元素:
buildTemplate(fragment) { let nodeList = [...fragment.childNodes]; // 1.遍歷所有的節(jié)點(diǎn) nodeList.forEach(node => { }); }
buildTemplate 方法定義在 Compiler 類中,我們需要在 compile 方法中調(diào)用它:
// 2.利用指定的數(shù)據(jù)編譯內(nèi)存中的元素 this.buildTemplate(fragment);
然后我們在 buildTemplate 方法中完善我們的代碼,這里我就先直接上完整的實(shí)現(xiàn)代碼:
buildTemplate(fragment) { let nodeList = [...fragment.childNodes]; // 1.遍歷所有的節(jié)點(diǎn) nodeList.forEach(node => { // 2.需要判斷當(dāng)前遍歷到的節(jié)點(diǎn)是一個(gè)元素還是一個(gè)文本 if (this.vm.isElement(node)) { // 是一個(gè)元素 this.buildElement(node); } else { // 不是一個(gè)元素 this.buildText(node); } }); } buildElement(node) { // 可以通過 node.attributes 獲取到當(dāng)前元素上所有的屬性 let attrs = [...node.attributes]; // 1.遍歷所有的屬性 attrs.forEach(attr => { let {name, value} = attr; if (name.startsWith('v-')) { console.log('是Vue的指令, 需要我們處理', name); } }); } buildText(node) { // 可以通過 node.textContent 獲取到當(dāng)前文本節(jié)點(diǎn)的內(nèi)容 let content = node.textContent; // 編寫一個(gè)正則表達(dá)式, 用來匹配 {{}} // 如下正則表達(dá)式的含義是: 匹配 {{}} 中間的內(nèi)容 // /: 正則表達(dá)式通常以斜杠 / 開始和結(jié)束,表示正則表達(dá)式的開始和結(jié)束。 // \{ 和 \}: 這些是轉(zhuǎn)義字符,用于匹配實(shí)際的花括號 { 和 }?;ɡㄌ栐谡齽t表達(dá)式中具有特殊意義,因此需要使用反斜杠進(jìn)行轉(zhuǎn)義。 // \{\{ 和 \}\}: 這是正則表達(dá)式的起始和結(jié)束部分,用于匹配雙花括號 {{ 和 }}。 // .+?: 這部分用于匹配雙花括號內(nèi)的任意字符,. 表示匹配任意字符,+ 表示匹配一個(gè)或多個(gè)前面的字符,? 表示非貪婪匹配,即盡可能匹配最短的內(nèi)容。這樣確保匹配到最近的結(jié)束雙花括號 }}。 // /g: g 是正則表達(dá)式的標(biāo)志,表示全局匹配,即匹配字符串中的所有符合條件的部分。 // /i: i 也是正則表達(dá)式的標(biāo)志,表示不區(qū)分大小寫匹配,這意味著 {{...}} 和 {{...}} 都會(huì)被匹配到。 // 因此,這個(gè)正則表達(dá)式可以用于在字符串中找到并提取所有的 {{...}} 結(jié)構(gòu),不區(qū)分大小寫,不貪婪匹配,且匹配所有出現(xiàn)的情況。 let reg = /\{\{.+?\}\}/gi; if (reg.test(content)) { console.log('是一個(gè)文本節(jié)點(diǎn), 需要我們處理', content); } }
好了,我們來看一下效果,我們在瀏覽器中打開,然后打開控制臺,可以看到如下的效果:
發(fā)現(xiàn),只有 v-model 指令被處理, {{}}
沒有被處理,如下圖我框出了 <p>
:
也就是說我們循環(huán)節(jié)點(diǎn)的時(shí)候,只循環(huán)了一層,沒有循環(huán)到 <p>
標(biāo)簽中的文本節(jié)點(diǎn),所以我們需要修改一下 buildTemplate 方法, 讓它支持遞歸,處理子元素(處理后代):
// 處理子元素(處理后代) this.buildTemplate(node);
改造后,我們再來看一下效果,可以看到 {{}}
也被處理了:
好了,到這里我們就實(shí)現(xiàn)了查找指令和模板的功能,下一篇我們來繼續(xù)完善一下我們的不完整的代碼,一步一步來慢慢撕。
到此這篇關(guān)于vue查找指令和模板的文章就介紹到這了,更多相關(guān)vue查找指令和模板內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue.js 中 axios 跨域訪問錯(cuò)誤問題及解決方法
這篇文章主要介紹了Vue.js 中 axios 跨域訪問錯(cuò)誤問題及解決方法,非常不錯(cuò),具有一定的參考借鑒價(jià)值 ,需要的朋友可以參考下2018-11-11vue實(shí)現(xiàn)類似淘寶商品評價(jià)頁面星級評價(jià)及上傳多張圖片功能
最近在寫一個(gè)關(guān)于vue的商城項(xiàng)目,然后集成在移動(dòng)端中,開發(fā)需求中有一界面,類似淘寶商城評價(jià)界面!接下來通過本文給大家分享vue實(shí)現(xiàn)類似淘寶商品評價(jià)頁面星級評價(jià)及上傳多張圖片功能,需要的朋友參考下吧2018-10-10elementPlus?的el-select在提示框關(guān)閉時(shí)自動(dòng)彈出的問題解決
這篇文章主要介紹了elementPlus?的el-select在提示框關(guān)閉時(shí)自動(dòng)彈出閉時(shí)自動(dòng)彈出的問題,主要問題就是因?yàn)閒ilterable屬性,根本解決方案是選中的時(shí)候讓他失去焦點(diǎn)?el-select有一個(gè)visible-change事件,下拉框出現(xiàn)/隱藏時(shí)觸發(fā),感興趣的朋友跟隨小編一起看看吧2024-01-01利用vue-router實(shí)現(xiàn)二級菜單內(nèi)容轉(zhuǎn)換
這篇文章主要介紹了如何利用vue-router實(shí)現(xiàn)二級菜單內(nèi)容轉(zhuǎn)換,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-11-11Vue+penlayers實(shí)現(xiàn)多邊形繪制及展示
這篇文章主要為大家詳細(xì)介紹了Vue+penlayers實(shí)現(xiàn)多邊形繪制及展示,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12vue移動(dòng)端設(shè)置全屏背景的項(xiàng)目實(shí)踐
本vue移動(dòng)端項(xiàng)目設(shè)置全屏背景,關(guān)鍵是要找對文件,然后添加background屬性即可,文中通過示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-08-08詳解Vue如何將多個(gè)空格被合并顯示成一個(gè)空格
這篇文章主要為大家詳細(xì)介紹了在Vue中如何將多個(gè)空格被合并顯示成一個(gè)空格,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-04-04