// 实现渲染自定义组件
main.js
import {render, Component, createElement} from './toy-react.js'// window.a = <div id="app" class="head"></div>class Hello extends Component {render () {return <div>{this.children}</div>}}window.a = <Hello id="app" class="head"><span>1</span><span>2</span><span><h1>3</h1><h1>4</h1></span>hello</Hello>render(window.a, document.body)
toy-react.js
export class Component {constructor() {this.props = Object.create(null);this.children = [];this._root = null;}setAttribute(name, value) {this.props[name] = value}appendChild(component) {this.children.push(component)}get root() {if (!this._root) {this._root = this.render().root}return this._root}}class ElementWrapper {constructor(type) {this.root = document.createElement(type)}setAttribute(name, value) {this.root.setAttribute(name, value)}appendChild(component) {this.root.appendChild(component.root)}}class TextWrapper {constructor(content) {this.root = document.createTextNode(content)}}export function createElement(tagName, attributes, ...rest) {let elementif (typeof tagName == 'string') {element = new ElementWrapper(tagName)} else {element = new tagName}if (typeof attributes === 'object' && attributes instanceof Object) {for (const key in attributes) {element.setAttribute(key, attributes[key])}}let insertChildren = (children) => {console.log(children)for(const child of children) {if (typeof child == 'string') {child = new TextWrapper(child)}if ((typeof child == 'object') && (child instanceof Array)) {insertChildren(child)} else {element.appendChild(child)}}}insertChildren(rest)return element}export function render(component, parentElement) {parentElement.appendChild(component.root)}
