ちょっと詰まったところがあったのでメモがわりに。
$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つ以上設置した場合、後に配置した方に上書きされるのだった。
これに気付かず型チェックやら何やらの判定をコンソールに吐き出して散々デバッグする苦い目にあったのでメモ替わりに投稿。
他に気をつける事
コンポーネントインスタンスにアクセスする関係上、親コンポーネントがレンダリングされていない状態で既に処理を行っている
created
やbeforeMount
では当然使えない。computed
も最初の処理時にDOM要素が無いのでif条件で何とかしないと使えない。
あとAxiosとかの非同期処理で引っ張ってきたデータを元にリストレンダリングしている場合、
当然非同期処理の終了を待たないと$refs
の中を見ても何も無いので注意。