请多看代码注释
入口index.js
// 先把React和React-dom换成mReact和mReact-dom
import React, { Component } from "./mReact";
import ReactDOM from "./mReact-dom";
import "./index.css";
// function类型的组件
function Comp(props) {
return <h2>hi{props.name}</h2>;
}
// class类型组件
class Comp2 extends Component {
render() {
return (
<div>
<h2>hi{this.props.name}</h2>
</div>
);
}
}
const users = [{ name: "tom", age: 20 }, { name: "jerry", age: 30 }];
const jsx = (
<div id="demo">
<span>hi1</span>
<span>hi2</span>
<div>
<span>hi1</span>
<span>hi2</span>
</div>
<Comp name="functionkaikeba" />
<Comp2 name="classkaikeba" />
<ul>
<li>wo--111</li>
{users.map((item, index) => (
<li key={index}>
{item.name}--{item.age}
</li>
))}
</ul>
</div>
);
ReactDOM.render(jsx, document.querySelector("#root"));
mReact.js
1.createElement生成虚拟DOM
2.Component被继承的根类
import { createVNode } from "./mvdom";
//生成虚拟dom
function createElement(type, props, ...children) {
props.children = children;
delete props.__source;
delete props.__self;
//判断标签类型
let vtype;
if (typeof type === "string") {
vtype = 1;
} else if (typeof type === "function") {
//isClassComponent继承的静态属性,用来判断组件类型
if (type.isClassComponent) {
vtype = 2;
} else {
vtype = 3;
}
}
console.log(vtype, type, props);
return createVNode(vtype, type, props);
}
export default { createElement };
export class Component {
//区分组件是function还是class
static isClassComponent = true;
constructor(props) {
this.props = props;
this.state = {};
}
setState() {}
}
mReact-dom.js
import { initVNode } from "./mvdom";
function render(vnode, container) {
//虚拟dom转成真实dom
const node = initVNode(vnode);
//把都挂载到root节点上
container.appendChild(node);
}
export default { render };
mvdom.js
//vdom转换为dom
//diff
//vtype元素类型:1-html元素;2-function组件;3-class组件
// 在mReact中用到返回虚拟dom
export function createVNode(vtype, type, props) {
const vnode = { vtype, type, props };
return vnode;
}
//vdom转换为dom
export function initVNode(vnode) {
const { vtype } = vnode;
console.log(vtype);
if (!vtype) {
//文本节点
return document.createTextNode(vnode);
}
if (vtype === 1) {
//原生元素
return createElement(vnode);
} else if (vtype === 2) {
//class组件
return createClassComp(vnode);
} else if (vtype === 3) {
//函数组件
return createFuncComp(vnode);
}
}
function createElement(vnode) {
const { type, props } = vnode;
//type是元素标签
const node = document.createElement(type);
//处理属性
const { key, children, ...rest } = props;
Object.keys(rest).forEach(k => {
if (k === "className") {
node.setAttribute("class", rest[k]);
} else if (k === "htmlFor") {
node.setAttribute("for", rest[k]);
} else {
node.setAttribute(k, rest[k]);
}
});
children.forEach(c => {
if (Array.isArray(c)) {
c.forEach(n => node.appendChild(initVNode(n)));
} else {
node.appendChild(initVNode(c));
}
});
return node;
}
function createClassComp(vnode) {
//type是class组件的声明
const { type, props } = vnode;
const component = new type(props);
const vdom = component.render();
return initVNode(vdom);
}
function createFuncComp(vnode) {
//type是函数
const { type, props } = vnode;
const vdom = type(props);
return initVNode(vdom);
}