<!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>