基礎からメモ: Vue.js CH2-p85 DOMの直接参照
DOMに直接アクセスするには、インスタンス・プロパティの$el
と$refs
を使う。これらは、ライフサイクルで言うとmounted
(インスタンスのマウント後)以降でなければ使えない。
$el
$el
は、コンポーネントのテンプレートを囲っているルート要素を指す。
var app = new Vue({ el: '#app', mounted: function() { console.log(this.$el); } });
コンソールに<div id="app">........</div>
という形でルート要素が表示されているはずだ。
$refs
ルート以外の要素は、ref
と$refs
でアクセスする。ref
はアクセスされるテンプレート側につける特殊な属性。
[index16.html]
<div id="app"> <p ref="hello">Hello</p> .......... </div>
このようにref
属性で何らかの名前を付けておき、次のようにアクセスする。
[main02.js]
var app = new Vue({ el: '#app', mounted: function() { console.log(this.$refs.hello); // <- ref属性の付いたp要素のDOMを指す。 }, });
コンソールにp要素のDOMが表示される。
<p>Hello</p>
$el や $refs は仮想DOMの変更で上書きされる
$el
や $refs
は、仮想DOMではない。操作するたびに描画するので、仮想DOMがデータの変更に応じて描画すると上書きされてしまうことがある。そのため、$el
や $refs
は一時的な変更でのみ使うべき。
例えば次のようにDOMから数値を取得し、ボタンをクリックするたびにその数値を+1するメソッドを紐付ける。そのうえでv-if
で表示・非表示を切り替えるボタンを設置する。
<button v-on:click="handleClick">カウントアップ</button> <p ref="count" v-if="show">0</p> <button v-on:click="show=!show">v-if 表示/非表示</button>
カウントアップというボタンを押すと数値が1ずつアップするが、一度v-if
を使ったボタンで非表示にし表示に戻すと数値が 0 に戻っているはずだ。
これに対して次のようなv-show
を使った表示・非表示を切り替えるボタンを設置すると、スタイルで非表示にしているだけなので、数値はブラウザで再読み込みしないかぎり維持される。v-show
はv-if
と違い仮想DOMを変更しないからだ。
<p ref="count2" v-show="ok">0</p> <button v-on:click="ok=!ok">v-show 表示/非表示</button>
Vue側は次のようになっている。
var app = new Vue({ el: '#app', data: { show: true, ok: true }, methods: { handleClick() { var count = this.$refs.count; var count2 = this.$refs.count2; if (count) { count.innerText = parseInt(count.innerText, 10) + 1; } if (count2) { count2.innerText = parseInt(count2.innerText, 10) + 1; } } } });
- DOMに直接アクセスするには、インスタンス・プロパティの
$el
と$refs
を使う。$el
や$refs
での変更は仮想DOMの変更で上書きされるので、一時的なDOMの操作に使う。