要是实在不知道要干什么,那就喝两杯思路就来了!

导航菜单

关于虚拟DOM的理解

对于真实 DOM 树来讲,其实就是一棵 DOM 树,为了减少频繁操作,尽而出现了虚拟 DOM,以减少浏览器的性能开销。下面我将实现使用一棵对象树来渲染成一个真实 DOM 树的案例,以更好的理解框架中的虚拟 DOM 是如何运行的。


一、根节点部分

<div id="app"></div>


二、对象 Tree 数据部分

var vdom = [
    {
        name: 'div',
        attr: {
            class: 'test',
            style: {
                fontSize: '36px'
            }
        },
        prop: {
            innerText: 'Hello'
        },
        children: [
            {
                name: 'h1',
                attr: {
                    style: {
                        color: '#ffaa00',
                        textShadow: '5px 5px 5px rgba(255, 122, 188, 0.3)'
                    }
                },
                prop: {
                    innerText: 'Hello World!'
                }
            }
        ]
    },
    {
        name: 'img',
        attr: {
            style: {
                width: '240px',
                borderRadius: '8px',
                border: '1px solid #ff4400'
            },
            src: 'http://k.sinaimg.cn/n/sinakd20117/76/w1080h596/20210126/4257-kicwvzq6908590.jpg/w700d1q75cms.jpg?by=cms_fixed_width'
        }
    },
    {
        name: 'ul',
        children: [
            {
                name: 'li',
                attr: {
                    style: {
                        color: '#ff4400',
                        fontWeight: 'bold'
                    }
                },
                prop: {
                    innerText: '数据1'
                }
            },
            {
                name: 'li',
                prop: {
                    innerText: '数据2'
                }
            },
            {
                name: 'li',
                attr: {
                    style: {
                        color: '#3388ff',
                        fontWeight: 'bold'
                    }
                },
                prop: {
                    innerText: '数据3'
                }
            }
        ]
    },
    {
        name: 'div',
        attr: {
            style: {
                borderTop: '1px solid #cccccc',
                paddingTop: '20px'
            }
        },
        children: [
            {
                name: 'button',
                attr: {
                    style: {
                        cursor: 'pointer',
                        marginRight: '16px'
                    }
                },
                prop: {
                    innerText: '取消',
                    onclick: function () {
                        alert('已经取消');
                    }
                }
            },
            {
                name: 'button',
                attr: {
                    style: {
                        cursor: 'pointer'
                    }
                },
                prop: {
                    id: 'confirmBtn',
                    innerText: '确认',
                    onclick: function () {
                        alert('确认成功');
                    }
                }
            }
        ]
    }
];


三、渲染函数部分

function render (app, vdom) {

    for (var i = 0; i < vdom.length; i++) {
        var node = document.createElement(vdom[i].name);
        var attr = vdom[i].attr;
        var prop = vdom[i].prop;

        if (attr) {
            for (var key in attr) {
                if (key === 'style') {
                    for (var styKey in attr[key]) {
                        node.style[styKey] = attr[key][styKey];
                    }
                } else {
                    node.setAttribute(key, attr[key]);
                }
            }
        }

        if (prop) {
            for (var key in prop) {
                node[key] = prop[key];
            }
        }

        app.appendChild(node);

        if (vdom[i].children && vdom[i].children.length) {
            render(node, vdom[i].children);
        }

    }

    app.appendChild(node);
    
}


四、渲染效果

微信截图_20240108114726.png

发表评论