<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.dialog{
width: 300px;
height: 300px;
margin:30px auto;
border:1px solid #333;
padding:30px;
}
</style>
</head>
<body>
<!--
Dom操作 为啥比较慢?
1. 臃肿 有年限
2. 图形输出
-->
<div id="root">
<p></p>
<Cmp1 click="fn1" mouseover="fn2"></Cmp1>
<UserLogin></UserLogin>
</div>
<script>
// 组件渲染
function render(options) {
let root;
// 判断属性类型
if(typeof options.root === 'string') {
root = document.querySelector(options.root);
if(!root) {
throw new Error(`找不到根元素 ${options.root}`)
}
} else if(options.root instanceof HTMLElement) {
let tags = options.root.getElementsByTagName('*');
tags = Array.from(tags);
// 找出自定义组件标签
tags.forEach(element => {
// 找到这是自定义组件
if(element.constructor === HTMLUnknownElement){
for (let cmpName in options.components) {
if(cmpName.toUpperCase() === element.nodeName) {
let CmpCls = options.components[cmpName];
// 生成一个类的实例
let cmp = new CmpCls();
let res = cmp.render();
// 获取组件定义的 属性和方法
if(element.hasAttribute("click")){
res.addEventListener('click', options.method[element.getAttribute("click")])
}
if(element.hasAttribute("mouseover")){
res.addEventListener('mouseover', options.method[element.getAttribute("mouseover")])
}
element.parentNode.replaceChild(res, element);
}
}
}
});
}
}
// 抽象的父类
class Component {
render() {
throw new Error('render is required');
}
}
class Cmp1 extends Component {
render() {
let div = document.createElement('div');
div.innerHTML = '我是cpm1';
return div;
}
}
class UserLogin extends Component{
render() {
let div = document.createElement('div');
div.className = 'dialog';
div.innerHTML = '我是login';
return div;
}
}
render({
root: document.querySelector('#root'),
components: {
Cmp1,
UserLogin
},
method: {
fn1:() => {console.log('我是cpm1,你点击了我');},
fn2:() => {console.log('我是cpm1,你碰到我了');}
}
})
</script>
</body>
</html>