0
0

【Nuxt3】definePropsの分割代入の変数をリアクティブにしたい!

Last updated at Posted at 2024-09-06

閲覧頂き、ありがとうございます🙇

この記事は definePropsの分割代入 における、
リアクティブ状態の保持 のための備忘録です!

前提

name version
Nuxt.js v3.13.x
Vue.js v3.5.x

ざっくり3行まとめ💨

  • propsDestructure: true にすることで可能
  • Vue.js v3.5では、デフォルトで有効化される
  • Nuxt.js v3.13 上で動かした場合、内部的に Vue.js v3.5 でもデフォルトで無効の模様

経緯🧐

以下のように親からPropsを渡し、子で分割代入した際にリアクティブが失われる

Parent.vue
<script setup lang="ts">
const count = ref(0)
const countUp = () => {
  count.value++
}
</script>
<template>
  <div>
    <Child :count="count" />
    <button @click="countUp">カウントアップ</button>
  </div>
</template>
Child.vue
<script setup lang="ts">
const { count } = defineProps<{
  count: number
}>()
</script>
<template>
  <p>{{ count }}</p>
</template>

↓↓↓↓↓ 結果 ↓↓↓↓↓

ボタンを押しても、カウントアップされない状態となる🙅

解決方法📝

nuxt.config.tspropsDestructure を設定をする

nuxt.config.ts
export default defineNuxtConfig({
  vue: {
    propsDestructure: true,
  },
})

↓↓↓↓↓ 結果 ↓↓↓↓↓

ボタンを押して、カウントアップがリアルタイムに反映される🙆

最後に🍵

この設定があることに今日気付いたので備忘録として記事にしました!
設定することでPropsを扱う際に冗長的にならず可読性向上につながるのかなと思います。

また2024年9月Announcing Vue 3.5 によると、
こちらの設定がデフォルトで有効化される模様でした🙌

Reactive Props Destructure has been stabilized in 3.5. With the feature now enabled by default, variables destructured from a defineProps call in <script setup> are now reactive.

Reactive Props Destructureは3.5で安定しました。この機能はデフォルトで有効になり、<script setup>のdefineProps呼び出しからデストラクトされた変数はリアクティブになりました。

ただNuxt.js上だとやはりまだ設定が必要なようなので、
今後のアップデートに期待しましょう🙏

またこちらのアナウンスでは、
メモリ使用量の大幅改善や、
definePropsでの初期値を代入する方法で従来withDefaultsを使っていましたが、
そちらを使わず、分割代入内で渡すことが可能になるようでした!

【Before】
const props = withDefaults(
  defineProps<{
    count?: number
    msg?: string
  }>(),
  {
    count: 0,
    msg: 'hello'
  }
)

↓↓↓↓↓

【After】
const { count = 0, msg = 'hello' } = defineProps<{
  count?: number
  message?: string
}>()

まだまだ Vue.js / Nuxt.js の進化が止まらないので今後の情報も楽しみです☺️

参考

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