【Vue.js】htmlの要素(dom) を参照する + 子コンポーネントを$elを使って参照する
やりたいこと
Vue.jsにて、template言語ブロックのhtmlの要素(dom)をscript言語ブロックから参照したいと思います。参照する方法について調べたのでメモしておきます。
必要なこと
- 言語ブロックのtemplate言語ブロックの参照したい
dom
にref
を設定 - 言語ブロックの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のクラスを取得してみる
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を取得してみます。
ディレクトリ
親コンポーネントが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.vue
のthis.$refs['the-child']
を
↓
this.$refs['the-child'].$el.classList
に変えてみましょう。
すると下図のように、子コンポーネントのクラスを取得することができています。
まとめ
htmlのdomをscript言語ブロックから参照してみました。また、子コンポーネントも参照してみました。そのときに、子コンポーネントを参照する場合には、$el
を利用することでクラスを取得することができるようになりました。
備考
子コンポーネント(Vueのインスタンスのdom)を参照する場合には、this.$refs['もじ'].$el
でElementを参照できます。
コンポーネント内のdomを参照する場合には、this.$refs['もじ']
でElementを参照できます。
参考
- API — Vue.js, 入手先 https://jp.vuejs.org/v2/api/#ref
- 作者:MIO
- 発売日: 2018/05/29
- メディア: Kindle版