ホームページ >ウェブフロントエンド >jsチュートリアル >vue仮想DOMとは何ですか? vueの仮想DOMの使い方

vue仮想DOMとは何ですか? vueの仮想DOMの使い方

不言
不言オリジナル
2018-08-09 11:00:3412846ブラウズ

Vue の仮想 DOM は、js を使用して DOM 構造をシミュレートします。この記事の内容は、vue 仮想 DOM とは何かを友達に紹介することです。 vueの仮想DOMの使い方とともに、記事の具体的な内容を見ていきましょう。

1. 仮想 DOM が必要な理由

先ほど、テンプレートの解析とレンダリングは、ページを直接編集する代わりにドキュメントのフラグメントを使用して、コンパイル機能を通じて行われる単純な Vue のようなフレームワークを最初から作成しました。 DOM 要素の数は、データの変更が完了した後、appendChild 関数を通じて実際の DOM をページに挿入します。

ドキュメントのフラグメントが使用されていますが、実際の DOM は引き続き操作されます。

そして、DOM の操作にはコストがかかることがわかっているため、vue2.0 は仮想 DOM を使用して実際の DOM の操作を置き換え、最後に何らかのメカニズムを使用して実際の DOM の更新を完了し、ビューをレンダリングします。

いわゆる仮想 DOM は、実際には JS を使用して DOM 構造をシミュレートし、DOM の変更操作を JS 層に配置して DOM の操作を最小限に抑えます (主に、JS の操作が JS の操作よりもはるかに高速であるためだと個人的には考えています) DOM の操作) 回数がわかると、JS が効率的に実行されます)。次に、仮想 DOM の変更を前後 2 回比較し、変更された部分のみが再レンダリングされ、変更されていない部分は再レンダリングされません。

たとえば、次のような DOM 構造があります。

<ul id="list">
      <li class="item1">Item 1</li>
      <li class="item2">Item 2</li></ul>

JS オブジェクトを完全に使用して上記の DOM 構造をシミュレートでき、シミュレーション後は次の構造になります。

var vdom = {
    tag: &#39;ul&#39;,
    attr: {
        id: &#39;list&#39;,
    },
    children: [
        {
            tag: &#39;li&#39;,
            attrs: {
                className: &#39;item&#39;,
                children: [&#39;Item 1&#39;]
            },
        },
        {
            tag: &#39;li&#39;,
            attrs: {
                className: &#39;item&#39;,
                children: [&#39;Item 2&#39;]
            }
        }
    ]

}

JS によってシミュレートされた DOM 構造は、すべての DOM ノードの属性とメソッドをシミュレートするわけではないことに注意する必要があります (DOM ノード自体には多くの属性があり、これが DOM 操作のパフォーマンスを消費するポイントでもあるため) , ただし、データ操作に関連するプロパティとメソッドの一部のみをシミュレートします。

2. vue仮想DOMの使い方

Vueはバージョン2.0でvdomを導入しました。その vdom は、snabbdom ライブラリによって行われた変更に基づいています。 snabbdom は、オープンソースの vdom ライブラリです。

snabbdom の主な機能は、受信した JS でシミュレートされた DOM 構造を仮想 DOM ノードに変換することです。

まず、h 関数を通じて JS でシミュレートされた DOM 構造を仮想 DOM に変換し、次に patch 関数を通じて仮想 DOM を実際の DOM に変換してページにレンダリングします。

ページの最小限のレンダリングを保証するために、snabbdom は Diff アルゴリズムを導入します。これは、Diff アルゴリズムを使用して前後の 2 つの仮想 DOM の違いを見つけ、変更された DOM ノードのみを再レンダリングせずに更新します。 DOM ノードを変更しました。

ここでは、snabbdom がどのようにこれを行うかを説明するために snabbdom のソースコードを分析するつもりはありません (主に、この段階ではそのレベルではないためです、笑) さらに、多くの学生がすでに同様の分析を行っています。記事の最後に添付します)。

snabbdom を使用する観点から、Vue の仮想 DOM がビューのレンダリングをどのように完了するかを見ていきます。

まず、snabbdom の 2 つのコア API の機能を見てみましょう。

  • h() 関数: 受信した JS シミュレートされた DOM 構造テンプレートを vnode に変換します。 (vnode は純粋な JS オブジェクトです)

  • patch() 関数: 仮想 DOM ノードをページにレンダリングします。

snabbdom の実際の機能を確認するための例を提供します。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title></head><body>
    <p id="container"></p>
    <button id="btn-change">change</button>
    <!-- 引入snabbdom库,先不必纠结为什么这样引入,以及每个文件的作用。本篇文章只是介绍一下虚拟DOM的工作方式,并不涉及原理解析
    主要是因为博主目前功力尚浅,有兴趣的小伙伴可以另行研究 -->
    <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom.js"></script>
    <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-class.js"></script>
    <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-props.js"></script>
    <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-style.js"></script>
    <script src="https://cdn.bootcss.com/snabbdom/0.7.1/snabbdom-eventlisteners.js"></script>
    <script src="https://cdn.bootcss.com/snabbdom/0.7.1/h.js"></script>
    <script>
        //定义patch函数
        var patch = snabbdom.init([
            snabbdom_class,
            snabbdom_props,
            snabbdom_style,
            snabbdom_eventlisteners
        ])        //定义h函数
        var h = snabbdom.h;        //生成一个vnode
        var vnode = h(&#39;ul#list&#39;,{},[
            h(&#39;li.item&#39;,{},[&#39;Item 1&#39;]),
            h(&#39;li.item&#39;,{},[&#39;Item 2&#39;]),
        ])
     //console.log(vnode);
        //获取container
        var container = document.getElementById(&#39;container&#39;);
        patch(container,vnode);//初次渲染

        var btn = document.getElementById(&#39;btn-change&#39;);
        btn.onclick = function() {            
        var newVnode = h(&#39;ul#list&#39;,{},[
                h(&#39;li.item&#39;,{},[&#39;Item 1&#39;]),
                h(&#39;li.item&#39;,{},[&#39;Item B&#39;]),
                h(&#39;li.item&#39;,{},[&#39;Item 3&#39;]),
            ])
            patch(vnode,newVnode);//再次渲染       
            vnode = newVnode;//将修改后的newVnode赋值给vnode              
            }    
            </script>
            </body>
            </html>

アイデア分析:

  • まず、h 関数を通じて仮想 DOM ノードを作成し、patch 関数を通じて仮想 DOM をページにレンダリングします。

  • btnボタンをクリックすると、ul#listリストのデータが更新され、2番目のli要素の値が変更され、新しいli要素が追加されます。最初のli要素の値は変更されません。 patch 関数を使用して、更新されたデータを再度ページにレンダリングします。 2 番目と 3 番目の li のみが更新され、最初の li は変更されていないため再レンダリングされないことがわかります。

vue でのテンプレートの解析とレンダリングの核心は、snabbdom の h() と patch() に似た関数を通じて、最初のレンダリングの場合はテンプレートがまず vnode に解析され、次に patch(コンテナー、vnode) は、vnode をページにレンダリングします。これが二次レンダリングの場合は、patch(vnode, newVnode) を使用して、最初に Diff アルゴリズムを通じて元の vnode と newVnode の違いを比較し、最小限のコストでページを再レンダリングします。 。

おすすめ関連記事:

diffの対象は仮想domです

以上がvue仮想DOMとは何ですか? vueの仮想DOMの使い方の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。