はじめに🥯
親コンポーネントから渡されたプロパティ(props
)のデータが変更されたとき、それを検出してビューを更新したい。
string
型や number
型のデータならばなんの手間もいらず変更を検出してくれるが、オブジェクトや配列データでは一手間が必要になってくる。
その一手間について記事にしてみた。
App | Version |
---|---|
Nuxt.js |
2.14.12 |
Nuxt(Vue) における変更検出の基本📝
Vue 公式のドキュメントに書いてある通り。
全てのコンポーネントには対応するウォッチャ(watcher)があり、コンポーネントのデータが変更されると setter
がこのウォッチャに通知する。
そして通知を受け取ったウォッチャからコンポーネントの再描画が行われる。
このデータ変更を検出させるために注意すべきなのが
-
オブジェクトデータの変更
-
配列データの変更
-
リアクティブなプロパティ
-
DOM操作をしたいとき
となる(詳細は公式のドキュメントや参考リンクを参照)。
props
のオブジェクトデータの変更を検出する🔍
今回つまったのは、親コンポーネントから props
オプションで渡されたオブジェクトデータの変更を検出する方法について。
検出可能にするには、ドキュメントより
-
親コンポーネントにおいてプロパティ値変更に
vm.$set
インスタンスメソッドを使う -
親コンポーネントにおいて新しいオブジェクトとして生成し直す
という方法が考えられるが、いちいち親コンポーネントで上記のことを気にかけるのが面倒くさい。
よって今回は子コンポーネントにおいて、watch
オプションを使って props
のオブジェクトを監視させる。
監視プロパティ(watch
)で変更を検出する
watch
オプションで props
のデータを監視し、変更に対して反応させる。
下記の例では nuxt-property-decorator ライブラリを利用しているので、代わりに @Watch
デコレータを利用している。
<script lang="ts">
import { Component, Prop, Vue, Watch } from 'nuxt-property-decorator'
@Component
export default class InputSearch extends Vue {
/** 入力値 */
message = ''
/** URLクエリパラメータ */
@Prop({ required: true, default: {} }) query!: Record<'tags', string>
/** `query.tags` プロパティの変更を監視 */
@Watch('query.tags', { immediate: true }) (1) (2) (3)
onUpdateQueryTags() { (4)
this.message = this.query.tags?.toString() ?? ''
}
}
</script>
1 | watch オプションの代わりに @Watch デコレータを利用。 |
2 | オブジェクトのプロパティを指定(ここでは query オブジェクトの tags プロパティ)して監視。 |
3 | Vue インスタンスの初期化時にも処理を実行したいので immediate オプションを有効化。 |
4 | 変更を検出したときに実行する処理を定義。 |
オブジェクトのネストされているプロパティ全てを監視したい場合は
|
おわりに😎
うっかりやらかす度合いが高そうなので、備忘録代わりに記事にしてみた。
props
でオブジェクトそのまま渡すのは落とし穴ができやすくて怖いなーって思ったり。