手写Vue渲染器render函数

使用js对象来描述UI更加的灵活。“这种对象”在vue框架中被称为虚拟DOM,渲染函数内部可以创建虚拟DOM,然后vue.js可以将其内容进行渲染。

1.渲染器的介绍

渲染器的作用就是把虚拟DOM渲染为真实DOM

思考下,我们有一个虚拟 DOM,如何将它转换为真实 DOM

const vnode = {
    tag: 'div',
    props: {
        onClick: () => alert('hello')
    },
    children: 'click me'
}

2.实现渲染函数renderer(只考虑创建没有考虑更新逻辑情况下)

  1. 两个参数。参数vnode表示虚拟 DOM 对象,container表示一个真实 DOM 元素,作为挂载点,渲染器会把虚拟 DOM 渲染到该挂载点

  2. 使用vnode.tag作为创建的dom标签el

  3. 遍历vnode.props,将属性 事件添加到DOM上(事件即给元素添加监听事件;)

  4. 处理 children(如果 children 是字符串,说明它是元素的文本子节点用createTextNode;如果children是数组则递归调用render函数渲染子节点并挂载到el元素下)

  5. 将元素添加到挂载节点container下

<div id="app"></div>
    <script>
        // 手写render函数将自己定义的vnode对象渲染到页面
        /**
         * @vnode 虚拟 DOM 对象
         * @container 一个真实 DOM 元素,作为挂载点,渲染器会把虚拟 DOM 渲染到该挂载点
         */
        function render(vnode, container) {
            // 使用vnode.tag作为创建的dom标签el
            let el = document.createElement(vnode.tag);

            // 遍历vnode.props,将属性 事件添加到DOM上(事件即给元素添加监听事件;)
            for (let key in vnode.props) {
                // 判断如果为事件则将其设置到el中
                if ((/^(on)/).test(key)) {
                    el.addEventListener(key.substr(2).toLowerCase(), vnode.props[key]);
                }
            }

            // 处理 children(字符串和数组)
            if (typeof vnode.children === "string") {
                el.appendChild(document.createTextNode(vnode.children));
            } else if (Array.isArray(vnode.children)) { //是数组进行遍历并递归调用render方法
                vnode.children.forEach(child => {
                    render(child, el);
                });
            }

            // 将元素添加到挂载节点container下
            container.appendChild(el);

        }

        // render函数测试
        const container = document.getElementById('app')
        const vnode = {
            tag: 'div',
            props: {
                onClick: () => alert('hello')
            },
            // children: 'click me'
            children: [{
                tag: 'h1',
                props: {
                    onClick: () => alert('h1')
                },
                children: '这是h1'
            },
            {
                tag: 'span',
                props: {
                    onClick: () => alert('span')
                },
                children: '这是span'
            }]
        }
        render(vnode, container)
    </script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值