[バイト記述テスト]仮想DOMのデータ構造を前提として、単純な仮想DOMを実装し、それをターゲットDOMツリーにレンダリングする方法

記事ディレクトリ

トピックの説明

次の仮想DOMのデータ構造を前提として、単純な仮想DOMを実装し、それをターゲットのDOMツリーにレンダリングする方法

// 样例数据
let demoNode = ({
    
    
    tagName: 'ul',
    props: {
    
    'class': 'list'},
    children: [
        ({
    
    tagName: 'li', children: ['douyin']}),
        ({
    
    tagName: 'li', children: ['toutiao']})
    ]
});

オブジェクトを次のようにレンダリングする関数renderを作成しますdemoNodedom

<ul class="list">
    <li>douyin</li>
    <li>toutiao</li>
</ul>

達成

/*
* @Params:
*     tagName(string)(requered)
*     props(object)(optional)
*     children(array)(optional)
* */
function Element({
     
     tagName, props, children}){
    
    
    if(!(this instanceof Element)){
    
    
        return new Element({
    
    tagName, props, children})
    }
    this.tagName = tagName;
    this.props = props || {
    
    };
    this.children = children || [];
}

これにより、仮想ツリーElementを任意に構築できます。DOMしかし、問題があります。仮想は結局仮想であり、ページ上にレンダリングする必要があります。そうしないと、役に立たなくなります。

それをどのように提示しますか?

上記から、これはツリーであることがわかっているのでDOM、トラバースすることで実際のノードを1つずつ作成できます。

  1. createElement;
  2. createTextNode;

これはツリーであるため、ツリー構造には2つのトラバーサルしかありません。

  1. 深さ優先走査(DFS)
    ここに画像の説明を挿入
  2. 実際の状況では幅優先探索(BFS)ここに画像の説明を挿入
    を使用する必要がありますがDFS、なぜですか?
    子ノードappendを親ノードに配置する必要があるため
    、を使用して、次のように関数をDFS実装しましょう。render
Element.prototype.render = function(){
    
    
    var el = document.createElement(this.tagName),
        props = this.props,
        propName,
        propValue;
    for(propName in props){
    
    
        propValue = props[propName];
        el.setAttribute(propName, propValue);
    }
    this.children.forEach(function(child){
    
    
        var childEl = null;
        if(child instanceof Element){
    
    
            childEl = child.render();
        }else{
    
    
            childEl = document.createTextNode(child);
        }
        el.appendChild(childEl);
    });
    return el;
};

この時点で、仮想DOMを指定された実際のDOMに簡単にレンダリングできます。次のように、アピールul仮想DOMをページ本体にレンダリングするとします。

var elem = Element({
    
    
    tagName: 'ul',
    props: {
    
    'class': 'list'},
    children: [
        Element({
    
    tagName: 'li', children: ['item1']}),
        Element({
    
    tagName: 'li', children: ['item2']})
    ]
});
document.querySelector('body').appendChild(elem.render());

結果

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_44761091/article/details/123720438