- 主要实现createElement方法 和 render方法
- createElement方法实现了对 组建props属性的创建和子节点属性children的创建
function createElement(type, config = {}, ...childrens) {
let props = {}
for (const key in config) {
props[key] = config[key]
}
props.children = childrens
return { type, props }
}
- render方法实现了对原生节点、函数节点、类节点的创建方式,函数组建和类组建最总都会得到原生节点。
- 得到原生节点递归判断是否含有子节点,有的话继续使用render方法,直到文本节点为止。
class Component {
constructor(props) {
props = this.props
}
static isReactComponent = true
}
function render(node, parent) {
if (typeof node === 'string') {
return parent.appendChild(document.createTextNode(node))
}
let { type, props } = node
if(type.isReactComponent) {
let classEle = new type(props).render()
type = classEle.type
props = classEle.props
}
else if (typeof type === 'function') {
let funEle = type(props)
type = funEle.type
props = funEle.props
}
let ele = document.createElement(type)
for (const key in props) {
switch (key) {
case 'children':
break
case 'className':
ele.className = props.className
break;
case 'style':
let styleObj = props.style
for (let attr in styleObj) {
ele.style[attr] = styleObj[attr]
}
break;
default:
ele.setAttribute(key, props[key])
}
}
if (Array.isArray(props.children)) {
props.children.forEach(element => {
render(element, ele)
});
}
parent.appendChild(ele)
}
function Hello() {
let msg = 'function component'
return createElement('h2', {style: { color: 'red' }}, msg)
}
class World extends Component{
constructor(props){
super(props)
}
render() {
return createElement('h2', {}, createElement('span', {}, 'class'))
}
}
let ele = createElement('h1', { className: 'hello' }, createElement('span', {style: { color: 'red' }}, 'hello'), createElement('span', {style: { 'fontSize': '18px' }}, ' world'), createElement(Hello, {}),createElement(World, {}))
render(ele, document.querySelector('#root'))
借鉴:www.cnblogs.com/lyt0207/p/1…