问题提出
面试中,面试官不免要问,关于v-if这类的指令,实现的原理是什么?
效果图示:
HTNL:
<body>
<div id="root">
<div v-if="true">我是指令的展示和隐藏</div>
<div v-if="false">我是要隐藏的</div>
</div>
</body>
我们期望在界面上,展示的效果是这样的:
如何实现
//第一步:获取元素DOM节点
var el = document.getElementById('root');
//第二步:处理DOM
function dealNode(el) {
var childNodes = el.childNodes;
[].slice.call(childNodes).forEach((node)=>{
if(node.nodeType == 1){
//节点元素的属性
var nodeAttrs = node.attributes;
console.log(nodeAttrs);
[].slice.call(nodeAttrs).forEach((attr) => {
var attrName = attr.name;
if(isDeretive(attrName)){
var exp = attr.value;
var dir = attr.name.substring(2);
console.log('指令类型',dir);
console.log('指令的值',exp);
if(dir == 'if' && (exp=='false')){
node.parentNode.removeChild(node);
}
}
});
}
//节点深层遍历
if(node.childNodes && node.childNodes.length){
dealNode(node);
}
})
}
dealNode(el);
function isDeretive(attr) {
return attr.indexOf('v-') == 0;
}
完整实例代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>属性指令</title>
</head>
<body>
<div id="root">
<div v-if="true">我是指令的展示和隐藏</div>
<div v-if="false">我是要隐藏的</div>
</div>
</body>
<script>
var el = document.getElementById('root');
function dealNode(el) {
var childNodes = el.childNodes;
[].slice.call(childNodes).forEach((node)=>{
if(node.nodeType == 1){
var nodeAttrs = node.attributes;
console.log(nodeAttrs);
[].slice.call(nodeAttrs).forEach((attr) => {
var attrName = attr.name;
if(isDeretive(attrName)){
var exp = attr.value;
var dir = attr.name.substring(2);
console.log('指令类型',dir);
console.log('指令的值',exp);
if(dir == 'if' && (exp=='false')){
node.parentNode.removeChild(node);
}
}
});
}
if(node.childNodes && node.childNodes.length){
dealNode(node);
}
})
}
dealNode(el);
function isDeretive(attr) {
return attr.indexOf('v-') == 0;
}
</script>
</html>