废话不多说,直接上代码~~
设置dom属性值
const setVDom = (node, key, value) => {
switch(key) {
// 增加样式
case 'style':
if (typeof value === 'string') {
node.style.cssText = value;
}
if (typeof value === 'object') {
for(let key in value) {
node.style[key] = value[key];
}
}
break;
// 赋值
case 'value':
let tagName = node.tagName || '';
tagName = tagName.toLowerCase();
if (['input', 'textarea'].includes(tagName)) {
node.value = value;
} else {
node.setAttribute(key, value);
}
break;
// 新增事件
case 'on':
for(let key in value) {
node['on'+key.toLowerCase()] = value[key];
}
console.log(node, key, value);
break;
// 增加其他属性
default:
node.setAttribute(key,value);
break;
}
}
创建 Element 类
class Element{
constructor(tagName, attrs = {}, child = []){
this.tagName = tagName;
this.attrs = attrs;
this.child = child;
}
render(){
let ele = document.createElement(this.tagName)
let attrs = this.attrs;
for(let key in attrs) {
setVDom(ele,key,attrs[key])
}
let childNodes = this.child;
childNodes.forEach((child) => {
let childEle = child instanceof Element ? child.render() : document.createTextNode(child);
ele.appendChild(childEle);
})
return ele;
}
}
实例化Element
const h = (tag,attr,child) => {
return new Element(tag,attr,child)
}
h函数的使用
const ulElement = h('ul', {id: 'list'}, [
h('li', {
style: {color: 'red',fontSize:'12px'}, /** 设置style样式 */
class: 'red', /** 设置类名 */
on: { /** 绑定事件 */
click(e) {
console.log(e);
}
}
},['绑定事件']),
h('li', {style: 'color: #ccc'},['创建元素li']),
h('li', {style: 'color: blue'}, [
'创建元素li',
h('input', {
style: 'color: green',
value: '创建元素input',
on: {
keyup(e) {
console.log(e.target.value)
}
}
}),
h('p', {style: 'color: green',value: 'green'},['创建元素p']),
])
]);
插入dom树到页面
<template>
<div ref="realDom"></div>
</template>
this.$refs.realDom.appendChild(this.RealDom)