0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Vueのhtml要素を参照する方のrefについて気づけなかった挙動について

Posted at

はじめに

 前回に引き続きVueのお話。これもまた挙動で悩んでいた問題。

 Composition APIでも引き続き有効なHTML要素自体を参照するref。Option APIの頃と違い、使い方はかなりスッキリしている。

test.js
const hogeelement = ref(null);
test.vue
<input type="file" ref="hogeelement" />

Option APIの頃は、やれ$refとしなきゃいけないとか少し気をつけないといけなかったが、Composition APIのほうだと他のリアクティブな変数と同様にref()(Vue.ref())で使いたい名前で定義するだけ。

問題

 HTML要素自体を参照するref。なぜか参照できない問題にぶち当たった。
 リアクティブにも気をつけていたし公式のリファレンスを見て使い方間違っていないと確認したはずなのに。
 多数のプロパティといくつか参照が必要な要素があったのでオブジェクトに内包してまとめて管理して使いたかったのだ。

test.js
const manageObj = Vue.ref({
  hogeelement: null,
  fooelement: null,
  prop1 : "aiueo",
  prop2 : 123
});
test.vue
<input type="file" ref="manageObj.hogeelement" />
<span ref="manageObj.fooelement"></span>

いざ他の処理内で manageObj.hogeelement.value とか manageObj.fooelement.scrollLeft = 123; という感じで使おうとしても、一切使えなかった。コンソールにエラーすら出ていない。しかし想定していたように処理が進まなくて悩んでいた。

解決

公式のリファレンスでいうとこのあたりがどうやらポイントなようだ。
image.png

 つまり、あるオブジェクト配下の子プロパティとしてHTML要素の参照を保持しておこうとしてもダメなのだろう。
 やるなら、最初の例の通りに const hogeelement = ref(null);として直接的な変数名として定義し、HTML側でもその名称だけで参照しなければいけない。

 ちなみに次のようにしても ダメ だった。

test.js
//---ダメだった例
const manageObj = {
  hogeelement : reactive(null),
  fooelement : ref(null)
};

 親オブジェクトリアクティブなオブジェクトでダメなら、親は普通のオブジェクトにして子をリアクティブにしてどうだ?・・・と考えたが、これでもできなかった。
 当然か。
 refキーがそもそも foo.bar と ドット区切りではキー名が一致できないということなんだろう。

終わりに

 HTML要素への参照を保持しておきたいなら、ref()関数は単体で定義しよう。自分自身の管理のためにあるオブジェクトの子プロパティに参照を保持して・・・とはできない。
 単体で定義するとごちゃごちゃしてきてわかりづらくなる・・・という問題が出てくるが仕方ない。というかそもそも直接的な参照をしないでも済むようにVueの仕組みが出来ているはずなので、使う機会が少なければそれに越したことはないのだ。
 気をつけたい。

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?