1.实现React
- 首先使用webpack或者parcel(使用文档: [https://zh.parceljs.org/getting_started.html]() )搭建环境
- 这时候我们在src目录下新建React.js文件,手动创建
let React = {}
React.createElement = (type,attrs,...children) => {
if(!type) {
return
}
return {
type,
attrs,
children
}
}
export default React
上述代码中,type指的是标签类型,attrs指的是值,children是子级
如:
<div id="app">
<span>hello react</span>
</div>
这时候我们就可以在index.js中引入React了,怎么样,是不是很简单
2.实现React-DOM
接下来就是第二步,实现虚拟dom的渲染,同样在src目录下新建一个react-dom.js文件
function ReactDOM(vnode, contanier) {
let element;
const { type, attrs, children } = vnode;
//1.判断DOM是否是文本节点,是 则创建文本节点,否则就创建DOM节点
if (typeof vnode === "string") {
element = document.createTextNode(vnode);
} else {
element = document.createElement(type);
}
//2.将attrs塞进DOM
setAttribute(element, attrs);
//3.在页面上显示
contanier.appendChild(element);
//这里是判断是否有子级,有则需要递归render逐个塞进element中
if (children && children.length) {
children.forEach((node) => {
ReactDOM(node, element);
});
}
}
//实现一个setAttribute方法
1.是否存在值,存在则进行下一步判断,否则return
2.值分为三类,一种是正常的如id等,一种是className,另一种是style
function setAttribute(element, attrs) {
if (!element || !attrs) {
return;
}
Object.keys(attrs).forEach((attr) => {
const value = attrs[attr];
if (attr === "className") {
element.setAttribute("class", value);
} else if (attr === "style") {
if (typeof value === "string") {
element.style.cssText = value;
} else if (isObject(value)) {
let str = "";
Object.keys(value).forEach((ele) => {
str += ele + ":" + value[ele] + ";";
element.style.cssText = str;
});
}
} else {
element.setAttribute(attr, value);
}
});
}
//判断是否为对象
function isObject(obj) {
return Object.prototype.toString.call(obj) === "[object Object]";
}
export default ReactDOM;
到这里就基本实现了react1.0版本,在index.js中我们来使用一下吧
import React from './src/react'
import ReactDOM from './src/react_-dom'
ReactDOM(
<div id="app" className="app-class">
oioioio
<div
id="span"
className="span-class"
style={{ color: "#f00", width: "100px" }}
>
span
</div>
</div>,
document.getElementById("root")
);
好了,看到这里是不是感觉很简单呢,那就动手试一下吧,后续将更新系列二,给它加入生命周期以及事件