// 实现渲染自定义组件

    main.js

    1. import {render, Component, createElement} from './toy-react.js'
    2. // window.a = <div id="app" class="head"></div>
    3. class Hello extends Component {
    4. render () {
    5. return <div>{this.children}</div>
    6. }
    7. }
    8. window.a = <Hello id="app" class="head">
    9. <span>1</span>
    10. <span>2</span>
    11. <span><h1>3</h1><h1>4</h1></span>
    12. hello
    13. </Hello>
    14. render(window.a, document.body)

    toy-react.js

    1. export class Component {
    2. constructor() {
    3. this.props = Object.create(null);
    4. this.children = [];
    5. this._root = null;
    6. }
    7. setAttribute(name, value) {
    8. this.props[name] = value
    9. }
    10. appendChild(component) {
    11. this.children.push(component)
    12. }
    13. get root() {
    14. if (!this._root) {
    15. this._root = this.render().root
    16. }
    17. return this._root
    18. }
    19. }
    20. class ElementWrapper {
    21. constructor(type) {
    22. this.root = document.createElement(type)
    23. }
    24. setAttribute(name, value) {
    25. this.root.setAttribute(name, value)
    26. }
    27. appendChild(component) {
    28. this.root.appendChild(component.root)
    29. }
    30. }
    31. class TextWrapper {
    32. constructor(content) {
    33. this.root = document.createTextNode(content)
    34. }
    35. }
    36. export function createElement(tagName, attributes, ...rest) {
    37. let element
    38. if (typeof tagName == 'string') {
    39. element = new ElementWrapper(tagName)
    40. } else {
    41. element = new tagName
    42. }
    43. if (typeof attributes === 'object' && attributes instanceof Object) {
    44. for (const key in attributes) {
    45. element.setAttribute(key, attributes[key])
    46. }
    47. }
    48. let insertChildren = (children) => {
    49. console.log(children)
    50. for(const child of children) {
    51. if (typeof child == 'string') {
    52. child = new TextWrapper(child)
    53. }
    54. if ((typeof child == 'object') && (child instanceof Array)) {
    55. insertChildren(child)
    56. } else {
    57. element.appendChild(child)
    58. }
    59. }
    60. }
    61. insertChildren(rest)
    62. return element
    63. }
    64. export function render(component, parentElement) {
    65. parentElement.appendChild(component.root)
    66. }