🐸

Vue 3.5 の「Reactive Props Destructure」について

に公開

はじめに

今更になってしまいますが、Vue3.5で追加された新機能の一部「Reactive Props Destructure(リアクティブなプロップス分割代入)」について紹介します。
これにより、これまで煩雑だった defineProps の扱いがシンプルになりました。

これまでの課題

以前の Vue(〜3.4)では、次のような制限がありました。

<script setup lang="ts">
const props = defineProps<{ count?: number; msg?: string }>()

// ❌ 分割代入するとリアクティブじゃなくなる!
const { count, msg } = props
</script>

そのため以下のような記述が必要でした

<script setup lang="ts">
const props = withDefaults(
  defineProps<{
    count?: number
    msg?: string
  }>(),
  {
    count: 0,
    msg: 'hello'
  }
)
</script>
  • withDefaults() でデフォルト値を指定
  • props.count のように都度アクセスする必要がある

つまり、コードが冗長でTypeScriptの型補完も煩雑になっていました。

Vue 3.5でどう変わったか

Vue 3.5 では defineProps() の分割代入がリアクティブになりました。

<script setup lang="ts">
const { count = 0, msg = 'hello' } = defineProps<{
  count?: number
  msg?: string
}>()
</script>
  • countmsg はそのままリアクティブ変数として使える。
  • count = 0 のように ネイティブ構文でデフォルトを指定できる。
  • withDefaults() が不要になり、シンプルで読みやすい。

まとめ

Vue 3.5 の最大の改善点は、「分割代入してもリアクティブを保つ」 ようになったことです。

これにより:

  • props.count のように毎回アクセスする必要がない
  • withDefaults() も不要
  • JavaScriptのネイティブ構文 (=) でデフォルト値を指定できる

つまり「普通の JavaScript の感覚で props を書ける」ようになったのが、
Vue 3.5 の嬉しい進化です 🎉

補足: オブジェクト構文との違い

従来の defineProps({ ... }) のオブジェクト構文では、
default プロパティでデフォルト値を設定できますが、
Vue 3.5 の新構文では TypeScript の型宣言とネイティブな = 構文で
同じことをよりシンプルに表現できます。

Discussion