每個(gè)節(jié)點(diǎn)都有一個(gè) nodeType 屬性,用于表明節(jié)點(diǎn)的類型,節(jié)點(diǎn)類型由? ? ?nodeType在vue中的應(yīng)用 在vue編譯的過(guò)程中需要查找html結(jié)構(gòu)中的雙大括號(hào),或者@事件等代表vue中的數(shù)據(jù)及方法的屬性值,通過(guò)編譯將查找到的部分使用vue實(shí)例中的屬性或方法替換 class Compile { // el是宿主元素選擇器 // vm是KVue實(shí)例 constructor(el, vm) { this.$vm = vm; this.$el = document.querySelector(el); // 先把模板移動(dòng)到fragment標(biāo)簽中,更新完成后在追加回來(lái) this.$fragment = this.node2Fragment(this.$el); // 執(zhí)行編譯 this.compile(this.$fragment); // 追加 this.$el.appendChild(this.$fragment); } node2Fragment(el) { // 移動(dòng)操作 const fragment = document.createDocumentFragment(); let child; while(child = el.firstChild) { // 移動(dòng)操作 fragment.appendChild(child); } return fragment } // 遞歸el,分別處理文本節(jié)點(diǎn)和元素節(jié)點(diǎn) compile(el) { const childNodes = el.childNodes; Array.from(childNodes).forEach(node => { if (node.nodeType == 1) { // 元素節(jié)點(diǎn) <p k-text="abc" @click="onClick"></p> // console.log('元素節(jié)點(diǎn):' node.nodeName); this.compileElement(node); } else if (this.isInter(node)) { // 文本節(jié)點(diǎn),且內(nèi)容是{{xxx}}實(shí)行 // console.log('插值文本:' node.textContent); this.compileText(node); } // 遞歸子節(jié)點(diǎn) if (node.childNodes && node.childNodes.length > 0) { this.compile(node); } }) } // 文本節(jié)點(diǎn),且內(nèi)容是{{xxx}}實(shí)行 isInter(node) { return node.nodeType == 3 && /\{\{(.*)\}\}/.test(node.textContent) } // 編譯元素節(jié)點(diǎn) compileElement(node) { // 遍歷所有屬性 const nodeAttrs = node.attributes; Array.from(nodeAttrs).forEach(attr => { // 規(guī)定:指令以k-xxx="yyy"命名 const attrName = attr.name; // 屬性名稱 k-xxx const exp = attr.value;// 屬性值 yyy if (attrName.indexOf('k-') == 0) { const dir = attrName.substring(2); // 執(zhí)行指令解析 this[dir] && this[dir](node, exp) } }) } compileText(node) { const exp = RegExp.$1; this.update(node, exp, 'text'); } // 通用update方法 update(node, exp, dir) { // 獲取更新函數(shù) let updator = this[dir 'Updator']; // 初始化,首次頁(yè)面賦值 updator && updator(node, this.$vm[exp]); // 創(chuàng)建Watcher new Watcher(this.$vm, exp, function(value) { updator && updator(node, value); }) } textUpdator(node, value) { node.textContent = value; } text(node, exp) { this.update(node, exp, 'text') } html(node, exp) { this.update(node, exp, 'html') } htmlUpdator(node, value) { node.innerHTML = value; } } 以上是簡(jiǎn)單的進(jìn)行屬性查找的示例,通過(guò)nodeType為1來(lái)判斷是元素節(jié)點(diǎn),還是文本節(jié)點(diǎn)并進(jìn)行相應(yīng)的操作。 ? 來(lái)源:https://www./content-1-435451.html |
|
來(lái)自: 印度阿三17 > 《開(kāi)發(fā)》