Vue.js v3.5からReactive Props Destructureという便利機能が追加されました🎉
個人のサービスをこれを使うようにリファクタリングしていたのですが、タイトルの通りReactive Props Destructureを使いつつWithDefaults
でデフォルト設定するとpropsのリアクティビティ性が失われるっぽい挙動がありハマったのでメモ📝
結論
「解決策としてはWithDefaults
を使わずにconst {msg = "default"} = defineProps({})
みたいな形で書き直してあげるとリアクティビティ性が維持されるようになった。」
Reactive Props DestructureはdefinePropsから直接利用されるケースでだけ有効になる設計になっているようです。
再現コード
元々以下のようなコードを書いていたのですが、
<script lang="ts" setup> const props = withDefaults(defineProps<{msg: string}>(), {msg: "Hello!!"}) </script> <template> <div> {{ msg }} </div> </template>
Reactive Props Destructureを使って以下のように書き直すとpropsのリアクティビティ性が失われて親コンポーネントから渡されたmsg
で書き換わらなくなった🤔
<script lang="ts" setup> const { msg } = withDefaults(defineProps<{msg: string}>(), {msg: "Hello!!"}) </script> <template> <div> {{ msg }} </div> </template>
以下のように書き直すと問題なくリアクティブ性が維持された🙆
<script lang="ts" setup> withDefaults(defineProps<{msg: string}>(), {msg: "Hello!!"}) </script> <template> <div> {{ msg }} </div> </template>
or
<script lang="ts" setup> const {msg = "Hello!!"} = defineProps<{msg: string}>(); </script> <template> <div> {{ msg }} </div> </template>
withDefaults
の有無によってこの辺りの挙動に破壊的変更が入らないように、なんかしら制御が入っているんですかね〜🤔(わからない)
バグっぽい気もしたのでissueあげてみた🎫