Vue.jsでDOM要素を参照して、スタイルやプロパティを取得・操作したい……。
なんて時に使うのがvm.$refs。
要素または子コンポーネントに参照を登録するためにrefを設定。
refを設定しておけば$refsから取得できるようになります。
最近、ループで出力した要素に対して、特定の条件下の場合はスタイルを操作したいってなことがありました。
その際にrefを利用したのですが、値が同じrefを持つ要素を複数設置すると、最後の要素しか取得できなくて「おぉぅ……」となったわけです。
ということで、ループ出力の際にrefの値を数列IDでユニークなものとし、そのrefを$refsで取得しスタイルを操作してみました。
値が同じrefを持つ要素を複数設置すると最後の要素しか取得できない
まずはこれですね。
「値が同じrefを持つ要素を複数設置すると最後の要素しか取得できない」。
1 2 3 4 5 |
<p ref="abc"></p> <p ref="abc"></p> <p ref="abc"></p> <p ref="abc"></p> <p ref="abc"></p> |
こんなHTMLがあったとして、
1 |
console.log(this.$refs.abc) |
と取得してみると、取れるのは最後の要素だけとなります。
上書きされているんですかね。
1 |
this.$refs.abc.style.display = 'none' |
なので、refの値がabcの要素を全てdisplay:noneにしようと思って下記のようにしてみても……。
1 2 3 4 5 |
<p ref="abc"></p> <p ref="abc"></p> <p ref="abc"></p> <p ref="abc"></p> <p ref="abc" style="display:none"></p> |
こうなっちゃう。
複数のrefに個別の値を設定し$refsで取得しスタイルを操作する
親にrefをつけて子を取得することもできるのですが、それぞれのインスタンスが順番に格納された配列が返ってくるので今回の意図とはちょっと違いまして。
それぞれのrefの値に数列IDを持たせて個別のものとしてみました。
1 2 3 4 5 |
<p ref="abc_1"></p> <p ref="abc_2"></p> <p ref="abc_3"></p> <p ref="abc_4"></p> <p ref="abc_5"></p> |
こうしておけば当たり前ですが、
1 |
this.$refs.abc_2.style.display = 'none' |
とかすれば、abc_2の値を持つrefが設置された要素だけにdisplay:noneが設定されます。
ただ、今回はこの要素数が比較的多かったので、
1 2 3 4 5 6 |
let arr = [2, 4] for (var i = 0; i < arr.length; i++) { let ref = this.$refs['abc_' + arr[i]] ref.style.display = 'none' } |
などとして、特定の条件下の数列IDを抽出して配列として格納し、それをループ処理で回すことでざっと設定することに。
1 2 3 4 5 |
<p ref="abc_1"></p> <p ref="abc_2" style="display:none"></p> <p ref="abc_3"></p> <p ref="abc_4" style="display:none"></p> <p ref="abc_5"></p> |
結果こんな感じで意図通りになりました。