仮想DOMってなに?② DOMを更新するタイミング

〇DOMを更新するタイミング

vue.jsは、DOMと紐づいたデータを更新してもすぐにはDOMを更新しません。

仮想DOMからDOMへの反映は、vue.jsのリアクティブシステムによる描画処理のタイミングで自動的に行われます。

このため、データを更新した直後にDOMにアクセスしてもまだ反映前の状態になっています。

 反映されたDOMにアクセスするためには、DOM更新を待ち受けるための仕組みを提供しているnextTickを使用する必要があります。

 

〇最適化によるDOMの再利用と副作用

 vue.jsで仮想DOMを利用している目的の1つとして、描画処理の性能を向上させる狙いもあります。実際描画処理においては、仮想DOMの差分検出アルゴリズムで、描画処理前の仮想Nodeをもとに、描画対象となるDOMに対してNodeの新規追加・更新・削除といったDOM操作を行います。

 

 このようにDOM操作を最小限にすることで、vue.jsでは描画処理の性能を向上させていますが、この副作用としてこちらが意図しない描画結果になることもあります。例えば、次のようなトグル形式の描画をみてみましょう。

 

```

<div v-if="toggle">
  A<input type="text">
</div>

<div v-else>
  B<input type="text">
</div>

``` 

 

このケースでは、toggleの更新によって描画が切り替わっても、もしinput要素に何か文字が入力された状態ならvalueの値は保持されたまま描画されます。これは、仮想DOMによる描画処理で更新の必要がないDOMを再利用しているためです。

 

 このような副作用を防ぐには、更新が必要な要素、またはそれを包含する要素に対してkey属性を付与することで、区別させて要素を更新します。このケースでは、input要素に対してkeyを設定することで、トグルするたびに新規に描画されるようになります。

 

```

<div v-if="toggle">
  A<input type="text" key="a">
</div>

<div v-else>
  B<input type="text" key="b">
</div>

```

 

このように、Vue.jsは仮想DOMの採用によって描画処理は柔軟的になりましたが、それに伴う先の例のような副作用もあるので描画においては注意が必要です。

 

jQueryなどのDOM操作とライブラリとの併用

 Vue.jsを使用すると、基本的にjQueryのようなDOM操作系ライブラリを併用することは減ります。マウントした要素内のDOMを直接操作しても、データが変わるわけではなく仮想DOMが更新されないためです。

 DOMの更新はデータバインディングが基本になり、DOMにアクセスする必要がある場合は$elや$refs,カスタムディレクティブといった機能がVue.jsから提供されています。他のライブラリと併用する場合も、なるべくVue.jsが提供する機能を使用したり、イベントバスやVuexを使用してデータを操作するようにしましょう。

 

参考文献:基礎から学ぶVue.js mio著