Madogiwa Blog

主に技術系の学習メモに使っていきます。

Reactive Props Destructureを使いつつWithDefaultsでデフォルト設定するとpropsのリアクティビティ性が失われるっぽい📝

Vue.js v3.5からReactive Props Destructureという便利機能が追加されました🎉

blog.vuejs.org

個人のサービスをこれを使うようにリファクタリングしていたのですが、タイトルの通りReactive Props Destructureを使いつつWithDefaultsでデフォルト設定するとpropsのリアクティビティ性が失われるっぽい挙動がありハマったのでメモ📝

結論

「解決策としてはWithDefaultsを使わずにconst {msg = "default"} = defineProps({})みたいな形で書き直してあげるとリアクティビティ性が維持されるようになった。」

Reactive Props DestructureはdefinePropsから直接利用されるケースでだけ有効になる設計になっているようです。

github.com

再現コード

元々以下のようなコードを書いていたのですが、

<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あげてみた🎫

github.com

参考

zenn.dev