2020年11月18日
数据驱动模型(3)-渲染
虚拟DOM生成带数据的虚拟DOM
- 该方法需要参数:虚拟DOM(vnode)、实例化对象时的数据(data)
- 判断节点类型(vnode.type):区分元素节点和文本节点
- 元素节点:通过data数据直接实例化VNode类(定义方式见数据驱动模型(2)虚拟dom块)生成dom;若含有子元素(vnode.children)则采用递归方式调用本方法
- 文本节点:采用通过正则表达式结合replace 方法获取需替换的值data,进行实例化VNode类
var rz = /\{\{(.+?)\}\}/g; function combine(vnode, data){ var tag = vnode.tag; var attr = vnode.attr; var value = vnode.value; var type = vnode.type; var children = vnode.children; var _vNode = null; if(type == 1){ // 元素节点 _vNode =new VNode(tag, attr, value, type); for(var i=0;i<children.length;i++){ _vNode.getData( combine(children[i], data) ) } }else if(type == 3){ // 文本节点 var res = value.trim().replace(rz, function(_,g){ return getValueByPath(data, g); }) _vNode =new VNode(tag, attr, res, type); } return _vNode; } function getValueByPath(obj, path){ var arr = path.split('.'); let res = obj; let prop; // arr.shift()取出数组的第一个值 while( prop = arr.shift() ){ res = res[ prop ]; } return res; }
带数据的虚拟DOM生成真是DOM(html)
- 该方法parseDom的参数包含:带数据的虚拟Dom(res)。判断节点类型。
- 元素节点时,创建元素节点(document.createElement);使用setAttribute方法绑定上相关属性。考虑子元素(children)则采用递归方式调用本方法parseDom
- 文本节点时,直接创建文本节点(document.createTextNode)
function parseDom (res){ let tag = res.tag; let type = res.type; let value = res.value; let attr = res.attr; let children = res.children; if(type == 1){ if(tag != undefined){ var ele = document.createElement(tag); } if(attr != undefined){ for(var i in attr){ ele.setAttribute(i,attr[i]); } } if(children.length != 0){ for(var i=0;i<children.length;i++){ val = ele.appendChild(parseDom(children[i])); } } }else if(type == 3){ var ele = document.createTextNode(value); } return ele; }