LoginSignup
172
131

More than 5 years have passed since last update.

[Vue.js] $refsでコンポーネント内の子要素を触る

Last updated at Posted at 2019-04-02

ちょっと詰まったところがあったのでメモがわりに。

$refsから子要素を触ろう

配置したコンポーネントを動的に取得して、スタイルとかプロパティを取得して弄りたかったり、処理を実行させたかったりする時がある。
そういう時は触りたい要素にrefを設定すると$refsから取得できるようになる。

<template>
  <hogehoge ref="hogehoge" />
</template>

<script>
  ...
    let component = this.$refs.hogehoge /// コンポーネントインスタンス hogehoge
  ...
</script>

リストレンダリングした物も$refsで取れる

v-forでリストレンダリングしたコンポーネントも$refsで取得することができる。

<template>
  <hogehoge v-for="item in hoge" ref="hogehoge" />
</template>

<script>
  ...
    let component = this.$refs.hogehoge[0] /// リストレンダリングした hogehoge の先頭要素
  ...
</script>

この例のように、リストレンダリングしたオブジェクトに$refsからアクセスすると
それぞれのインスタンスが順番に格納された配列が返ってくる。

ひらめいた

これ、同じref名を設定してやれば配列で格納されるって事じゃないの?
じゃあリストレンダリングの後に同じref名でコンポーネント設置してやれば
配列の最後に必ず特定の状態のコンポーネント入れられるんじゃね?

<template>
  <hogehoge v-for="item in hoge" ref="hogehoge" />
  <fugafuga ref="hogehoge" />
</template>

されない

そんな訳がなかった。
同名refが配列として格納されるのではなく、あくまでリストレンダリングしたコンポーネントを配列として返しているだけ
じゃあ上に書いたコードだとどのような結果になるかというと

<script>
  ...
    let component = this.$refs.hogehoge /// コンポーネントインスタンス fugafuga
  ...
</script>

<fugafuga>要素だけが取れる。
つまり同名のrefを持つコンポーネントを2つ以上設置した場合、後に配置した方に上書きされるのだった。
これに気付かず型チェックやら何やらの判定をコンソールに吐き出して散々デバッグする苦い目にあったのでメモ替わりに投稿。

他に気をつける事

コンポーネントインスタンスにアクセスする関係上、親コンポーネントがレンダリングされていない状態で既に処理を行っている
createdbeforeMountでは当然使えない。computedも最初の処理時にDOM要素が無いのでif条件で何とかしないと使えない。

あとAxiosとかの非同期処理で引っ張ってきたデータを元にリストレンダリングしている場合、
当然非同期処理の終了を待たないと$refsの中を見ても何も無いので注意。

参考

172
131
0

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
172
131