tomatoaiu の Tech Blog

プログラミングやツールについてのまとめブログ

【Vue.js】htmlの要素(dom) を参照する + 子コンポーネントを$elを使って参照する

やりたいこと

Vue.jsにて、template言語ブロックのhtmlの要素(dom)をscript言語ブロックから参照したいと思います。参照する方法について調べたのでメモしておきます。

必要なこと

  1. 言語ブロックのtemplate言語ブロックの参照したいdomrefを設定
  2. 言語ブロックのscript言語ブロックでthis.$refsを使う

実際に取得してみる

以下のようなtempate言語ブロックが存在しているとします。これの<p>this is dom</p>をscript言語ブロックからJavaScriptで参照できるようにしたいです。

<template>
  <p>this is dom</p>
</template>

環境

  • Node.js v12.13.0
  • Vue.js v2.6.11

コード

では、取得するコードを書いてみます。<p>this is dom</p>のpタグに、ref="the-text"を設定します。domを参照したいscript言語からは、mounted内で、this.$refs['the-text']とすることでdomを参照できるようになります。

<template>
  <p ref="the-text">this is dom</p>
</template>

<script>
export default {
  mounted () {
    console.log(this.$refs['the-text'])
  }
}
</script>

実行

console.log(this.$refs['the-text'])としているので、開発者ツールのコンソールに<p>this is dom</p>が表示されていれば成功です。

下図のようになっていることを確認できればきちんとdomをJavaScriptから参照することがで出来ています。

dom console
dom console

domのクラスを取得してみる

domを参照できるようになったので、classを取得してみたいと思います。といってもそんなに難しいことはなく、<p ref="the-text" class="the-class">this is dom</p>のようにclass="the-classを追加して、this.$refs['the-text'].classListのように、.classListを新たに追加するだけでクラスを取得することが出来ます。

<template>
  <p ref="the-text" class="the-class">this is dom</p>
</template>

<script>
export default {
  mounted () {
    console.log(this.$refs['the-text'].classList)
  }
}
</script>

正しく取得できていれば、下図のようにクラスのリストがコンソールに表示されているはずです。

domのクラスの取得結果
domのクラスの取得結果

子コンポーネントのdomを取得してみる

同じコンポーネントのdomを取得できるようになったので、今度はコンポーネント内から子コンポーネントのdomを取得してみます。

ディレクトリ

親コンポーネントがindex.vueになり、子コンポーネントがchild.vueになります。

.
├── child.vue
└── index.vue

コード

基本的には、前回のpタグが子コンポーネントのchildタグに変わっただけです。

↓親コンポーネント(index.vue)

<template>
  <child ref="the-child">this is dom</child>
</template>

<script>
import Child from './child.vue'

export default {
  components: {
    Child
  },
  mounted () {
    console.log(this.$refs['the-child'])
  }
}
</script>

↓子コンポーネント(child.vue)

<template>
  <p class="the-child-class">this is the child dom</p>
</template>

実行

コードが完成したので、結果をコンソールから見てみます。すると下図のようになります。

子コンポーネントを参照した結果
子コンポーネントを参照した結果

お気づきになるかもしれませんが、取得結果が違くなります。単純に、同コンポーネント内のdomを取得するのと子コンポーネントのdomを取得するのでは結果が違くなるのです。

同コンポーネント内のdomは、<p>もじ</p>になりますが、
子コンポーネントのdomは、VueComponentになります。

なぜ違うの?

おそらく子コンポーネントをimportしてcomponentsとして取り込んでいる最中に、子コンポーネントはVueのインスタンス化することによると考えられます。そのため、普通のdomとは違ったVueでラップされたdomになるようですね。

どうやって参照するの?

子コンポーネントをのクラスを取得しようとindex.vueのmounted()のコンソールログ関数の中身をthis.$refs['the-child'].classListのように変えてもundefinedになります。

そこで登場するのが、$elというVueのAPIになります。

$elを使うことで

index.vuethis.$refs['the-child']

this.$refs['the-child'].$el.classList に変えてみましょう。

すると下図のように、子コンポーネントのクラスを取得することができています。

child domのクラスリスト取得結果
child domのクラスリスト取得結果

まとめ

htmlのdomをscript言語ブロックから参照してみました。また、子コンポーネントも参照してみました。そのときに、子コンポーネントを参照する場合には、$elを利用することでクラスを取得することができるようになりました。

備考

子コンポーネント(Vueのインスタンスのdom)を参照する場合には、this.$refs['もじ'].$elElementを参照できます。
コンポーネント内のdomを参照する場合には、this.$refs['もじ']Elementを参照できます。

参考

基礎から学ぶ Vue.js

基礎から学ぶ Vue.js

  • 作者:MIO
  • 発売日: 2018/05/29
  • メディア: Kindle版