75
70

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Vueで直接DOMノードを参照するプロパティを知ってアハ体験したのでまとめてみた

Last updated at Posted at 2019-03-04

今日、Vueのコードを書いていて、ふと vm.$el の存在を思い出して猛烈に感動しました。
なので、Vueインスタンスから特定のDOM要素を参照できる方法を一覧してみようと思います。
ちなみに、途中までプロパティセレクタを使ったquerySelectorで、リストの特定要素を指定して意図通りに動いたものの……という顔をしてました

基本的に公式ドキュメントの API — Vue.js に書いてあることの引用です。

知ってマジ神だなって奴

vm.$el - コンポーネントのルートDOMを得る

型: Element
Vue インスタンスが管理している ルートな DOM 要素です。

hoge.vue
<template>
  <div class="hoge">
    <p v-on:click="click">hoge</p>
  </div>
</template>

<script>
default export{
  methods:{
    click(){
      // <div class="hoge">  DOM が入る
      console.log(this.$el) 
    }
  }
}
</script>

vm.$refs - 子DOM/子コンポーネントを得る

型: Object
ref 属性によって登録されたDOM 要素のオブジェクトとコンポーネントインスタンスです。

公式ドキュメントの 特別な属性 - ref と併せてお読みください。

<!-- vm.$refs.p は DOM ノード -->
<p ref="p">hello</p>

<!-- vm.$refs.child は child-component のインスタンス -->
<child-component ref="child"></child-component>

とのことなので、どこにrefをつけるかで返り値が変わるようです。
ドキュメントにもありますが、レンダリング後にvm.$refの値が入るようなので、この値が存在しなくてもエラーにならないようにハンドリングしてあげる必要があります。

一応できるやつ

vm.$parent - 親コンポーネントを得る

型: Vue instance
現在のインスタンスが1つ持つ場合は、親のインスタンスです。

親コンポーネントのインスタンスが返ります。 先程のvm.$elと組み合わせれば、親インスタンスのDOMノードが取得できますね。
まぁ、親のコンポーネントを操作するのはよほど密結合なコンポーネント同士でないと御法度でしょう。

 
<script>
default export{
  methods:{
    click(){
      this.$parent.$el // 親コンポーネントのルートなDOM要素
    }
  }
}
</script>

slotを使うなら使いそうなやつ

vm.$scopedSlots

型: { [name: string]: props => Array | undefined }
プログラム的にスロットにより配信されたコンテンツにアクセスするために使用されます。各名前付きスロット は自身に対応するプロパティを持ちます (例: slot="foo" のコンテンツは vm.$slots.foo で見つかります)。default プロパティは名前付きスロットに含まれない任意のノードを含みます。

とりあえず現状自分がSlotを使わなさそうなので詳細については調べてません。

#今回の要件ではあまりマッチしなさそうなもの

vm.$root

型: Vue instance
現在のコンポーネントツリーのルート Vue インスタンスです。現在のインスタンスが親を持たない場合、この値はそれ自身でしょう。

概ねvm.$parentと似たような使用感覚だと思うのですが、コンポーネントツリーのルートを取得しても Element 取得の用途ではあまり役に立たなさそうです。

vm.$children

型: Array
現在のインスタンスの直接的な子コンポーネントです。
$children に対して順序の保証がなく、リアクティブでないことに注意してください。あなた自身、データバインディングに対して $children を使用するためにそれを見つけようとする場合、子コンポーネントを生成するために配列と v-for を使用することを検討し、正しいソースとして配列を使用してください。

順序の保証がないというのは恐ろしいのでElementの取得用途では使いづらそうです。

まとめ

リストレンダリングされたコンポーネントの自分自身のエレメントを取得するときに良かったです。

また、動的にstyle計算するのに現在のDOMから値を取得したものを算出プロパティの計算に使うと、
現在のDOMの状態をリアルタイムに反映した値を作ることができると思います。
生DOMの値はリアクティブに参照できなかったデス。

値の参照用途として、VueインスタンスからDOM要素を直接参照する方法を知っておくのはかなり役立つのではないでしょうか。

余談

親のDOMがほしい

単に親DOMがほしいときは Element.parentNode で取れます
https://developer.mozilla.org/ja/docs/Web/API/Node/parentNode

子や孫のDOMが欲しい

DOM要素に対してもquerySelector が使えるので、先に絞り込んでその中から取得することもできます。
https://developer.mozilla.org/ja/docs/Web/API/Element/querySelector

75
70
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
75
70

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?