content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">

Diff算法

/**

* 创建元素

* @param type 类型

* @param props 参数

* @param children 子节点 = 数组 || 文字

*/

class Element {

constructor(type, props, children) {

this.type = type;

this.props = props;

this.children = children;

}

}

// 创建元素

function createElement(type, props, children) {

return new Element(type, props, children);

}

// 虚拟Dom 1

const vDOM = createElement('ul',

{

class: 'list',

style: 'width: 300px; height: 300px; background-color: orange'

},

[

createElement('li',

{class: 'item', 'data-index': 0},

[

createElement('p', {class: 'text'}, ['第1个选项'])

]),

createElement('li',

{class: 'item', 'data-index': 1},

[

createElement('p', {class: 'text'}, [

createElement('span', {

class: 'text'

}, [

'第2个列表选项'

])

])

]

),

createElement('li',

{class: 'item', 'data-index': 2},

['第3个列表选项']

)

]

);

/**

* 渲染函数虚拟DOM成真实的节点

* @method render

* @param vDOM 虚拟dom对象

* @return 返回真实的节点

*/

const render = (vDOM) => {

// 解析赋值 取出类型、参数和子节点

const {type, props, children} = vDOM;

// 获得根节点、并且把之后虚拟type转成节点

const el = document.createElement(type);

// 遍历属性

Object.keys(props).forEach(key => {

// 设置节点的属性和值

setAttrs(el, key, props[key]);

});

children.map(child => {

// 如果通过Element生成接着渲染?

// 是: 虚拟节点转元素

// 否: 创建文本节点

child = child instanceof Element

? render(child)

: document.createTextNode(child);

// 全部添加到每一级父元素、直到最顶级节点

el.appendChild(child);

});

return el;

};

/***

* 节点挂上属性

* @method setAttrs

* @param element 节点

* @param property 属性

* @param value 属性后的值

*/

function setAttrs(element, property, value) {

switch (property) {

// 或许是输入框

case 'value':

// 目前没测试value属性

if (element.tagName === 'INPUT' || element.tagName === 'TEXTART') {

// 输入框的值是value不是innerText

element.value = value;

} else {

element.setAttribute(property, value);

}

break;

// 如果是样式

case 'style':

element.style.cssText = value;

break;

// 默认情况就设置属性和值就好(不够严谨

default:

element.setAttribute(property, value);

break;

}

}

const realElement = render(vDOM);

// 获取到App元素

const App = document.querySelector('#app');

// 蹬蹬蹬~虚拟DOM转真实DOM成功

App.appendChild(realElement);

一键复制

编辑

Web IDE

原始数据

按行查看

历史

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐