daily-share
daily-share copied to clipboard
虚拟dom的实现方式(2020-2-18)
虚拟dom的实现方式
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)
}
// 设置属性的方法
function setAttr(node, key, value) {
// eslint-disable-next-line default-case
switch(key) {
case 'value' : // node是不是一个input或者是textarea
if (node.tagName.toUpperCase() === 'INPUT' || node.tagName.toUpperCase() === 'TEXTAREA') {
node.value = value
} else {
node.setAttribute(key, value)
}
break
case 'style' :
node.style.cssText = value
break
default :
node.setAttribute(key, value)
}
}
// 将虚拟dom专成真实dom
function render(eleObj) {
const el = document.createElement(eleObj.type)
// 给元素设置属性
for (let key in eleObj.props) {
setAttr(el, key, eleObj.props[key])
}
// 遍历子元素,是虚拟dom继续渲染
eleObj.children.forEach( child => {
// 判断child是否是元素,还是文本
child = (child instanceof Element) ? render(child) : document.createTextNode(child)
el.appendChild(child)
})
return el
}
// 将虚拟dom转化成真实dom进行渲染
function renderDom(el, target) {
target.appendChild(el)
}
export {
createElement,
render,
Element,
renderDom
}
import { createElement, render } from './diff'
let virtualDom = createElement('ul', { calss: 'list'}, [
createElement('li', { class: 'item'}, ['a']),
createElement('li', { class: 'item'}, ['b']),
createElement('li', { class: 'item'}, ['c'])
])
const el = render(virtualDom)
console.log(el)
console.log(virtualDom)