|
每個節(jié)點都有一個 nodeType 屬性,用于表明節(jié)點的類型,節(jié)點類型由?
? ?nodeType在vue中的應(yīng)用 在vue編譯的過程中需要查找html結(jié)構(gòu)中的雙大括號,或者@事件等代表vue中的數(shù)據(jù)及方法的屬性值,通過編譯將查找到的部分使用vue實例中的屬性或方法替換 class Compile {
// el是宿主元素選擇器
// vm是KVue實例
constructor(el, vm) {
this.$vm = vm;
this.$el = document.querySelector(el);
// 先把模板移動到fragment標(biāo)簽中,更新完成后在追加回來
this.$fragment = this.node2Fragment(this.$el);
// 執(zhí)行編譯
this.compile(this.$fragment);
// 追加
this.$el.appendChild(this.$fragment);
}
node2Fragment(el) {
// 移動操作
const fragment = document.createDocumentFragment();
let child;
while(child = el.firstChild) {
// 移動操作
fragment.appendChild(child);
}
return fragment
}
// 遞歸el,分別處理文本節(jié)點和元素節(jié)點
compile(el) {
const childNodes = el.childNodes;
Array.from(childNodes).forEach(node => {
if (node.nodeType == 1) {
// 元素節(jié)點 <p k-text="abc" @click="onClick"></p>
// console.log('元素節(jié)點:' node.nodeName);
this.compileElement(node);
} else if (this.isInter(node)) {
// 文本節(jié)點,且內(nèi)容是{{xxx}}實行
// console.log('插值文本:' node.textContent);
this.compileText(node);
}
// 遞歸子節(jié)點
if (node.childNodes && node.childNodes.length > 0) {
this.compile(node);
}
})
}
// 文本節(jié)點,且內(nèi)容是{{xxx}}實行
isInter(node) {
return node.nodeType == 3 && /\{\{(.*)\}\}/.test(node.textContent)
}
// 編譯元素節(jié)點
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'];
// 初始化,首次頁面賦值
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;
}
}
以上是簡單的進(jìn)行屬性查找的示例,通過nodeType為1來判斷是元素節(jié)點,還是文本節(jié)點并進(jìn)行相應(yīng)的操作。 ? 來源:https://www./content-1-435451.html |
|
|