Skip to content

07.实现 render、mount 和 createDOM进行初次渲染

具体代码变化过程请观看视频,这里把关键代码展示出来:

js
import { REACT_ELEMENT } from './utils'
function render(VNode, containerDOM){
    mount(VNode, containerDOM)
    // 有同学会觉得奇怪,为什么不把mount函数的逻辑放到这里,还少一次函数调用,
    // 事实上,render函数不仅仅只做挂载这样一件事情,只不过我们这里暂未涉及
}
function mount(VNode, containerDOM){
    let newDOM = createDOM(VNode)
    newDOM && containerDOM.appendChild(newDOM);
}
function createDOM(VNode){
    // 根据虚拟DOM创建真实DOM要做三件事情: 1.创建元素 2.处理子元素 3.处理元素属性
    const {type, props} = VNode
    let dom;
    if (type && VNode.$$typeof === REACT_ELEMENT) {
        dom = document.createElement(type);
    }
    // 处理子元素
    if(props){
        // 这里我们要纠正上一小节关于createElement的一行代码,children数组
        if (typeof props.children === 'object' && props.children.type) {
            mount(props.children, dom)
        } else if (Array.isArray(props.children)) {
            mountArray(props.children, dom);
        } else if (typeof props.children === 'string'){
            dom.appendChild(document.createTextNode(props.children));
        }
    }
    // 处理属性
    return dom
}
f
function mountArray(children, parent){
    if(!Array.isArray(children)) return
    for (let i = 0; i < children.length; i++) {
        if (typeof children[i] === 'string'){
            parent.appendChild(document.createTextNode(children[i]))
        }else{
            mount(children[i], parent)
        }
    }
}
const ReactDOM = {
    render
}
export default ReactDOM

我们来观察项目执行情况,会发现页面上展示了视频中我们所期待的字符串。不过虽然这里实现了render、mount、createDOM几个函数,但这里只是处理了最简单的场景,随着课程的深入,这些函数的内容还会不断完善。

基于 VitePress 构建