Vue 3のscript setupでのpropsの使い方
Vue 3のComposition APIと<script setup>
構文を使用すると、コンポーネントの記述がより簡潔になります。この記事では、<script setup>
でpropsを正しく定義し使用する方法について詳しく解説します。
問題点
元のコードでは、defineProps
でpropsを定義していますが、非同期関数内でpropsにアクセスする方法がわからないという問題がありました:
<script setup>
import { defineProps, reactive } from 'vue'
defineProps({
no: String
})
const init = async () => {
// props.no にどうやってアクセスする?
// const { data } = await getRoomByNo(props.no)
}
init()
</script>
基本的なpropsの定義方法
<script setup>
では、defineProps
関数を使用してpropsを定義します。これはコンパイル時のマクロであり、明示的なインポートは不要です。
<script setup>
const props = defineProps({
no: String,
isOpen: Boolean,
count: Number
})
console.log(props.no) // propsの値にアクセス
</script>
リアクティブなpropsの使用方法
propsをリアクティブに扱いたい場合、toRefs
を使用して分割代入することが推奨されます:
<script setup>
import { toRefs } from 'vue'
const props = defineProps({
no: String,
myId: Number
})
// リアクティブを保つためにtoRefsを使用
const { no, myId } = toRefs(props)
console.log(no.value) // .valueで値にアクセス
console.log(myId.value)
</script>
TypeScriptを使用した型定義
TypeScriptを使用する場合、より厳密な型チェックが可能です。
インターフェースを使用した方法
<script setup lang="ts">
interface Props {
disabled: boolean
loading: boolean
bordered: boolean
label?: string
}
const props = defineProps<Props>()
</script>
リテラル型を使用した方法
<script setup lang="ts">
type Color = 'primary' | 'info' | 'success' | 'error' | 'warning'
const props = defineProps<{
color: Color
size: 'small' | 'medium' | 'large'
}>()
</script>
デフォルト値の設定
JavaScriptの場合
<script setup>
defineProps({
isOpen: {
type: Boolean,
default: true
},
label: {
type: String,
default: 'Default Label'
}
})
</script>
TypeScriptの場合
<script setup lang="ts">
interface Props {
msg?: string
count?: number
}
const props = withDefaults(defineProps<Props>(), {
msg: 'hello',
count: 0
})
</script>
実際の使用例
以下は、propsを受け取るコンポーネントの完全な例です:
<template>
<div class="px-4 w-8/12 sm:w-3/12">
<img :src="src" :alt="alt" class="border-none rounded-full h-auto max-w-full align-middle" />
</div>
</template>
<script setup>
const props = defineProps({
src: String,
alt: String,
})
</script>
<template>
<div class="flex flex-wrap justify-center">
<CircleImage src="/file1.jpg" alt="one" />
<CircleImage src="/file2.svg" alt="two" />
</div>
</template>
<script setup>
import CircleImage from '@/components/CircleImage.vue'
</script>
注意点
WARNING
propsは読み取り専用です。子コンポーネント内でpropsを変更しようとしないでください。代わりに、親コンポーネントにイベントを発行して状態の変更を要求しましょう。
TIP
defineProps
はコンパイル時マクロであり、実行時には存在しません。JavaScript/TypeScriptの式の中で動的にpropsを定義することはできません。
まとめ
Vue 3の<script setup>
構文では、defineProps
を使用してpropsを定義します。TypeScriptを使用する場合は型安全性を高め、必要に応じてwithDefaults
でデフォルト値を設定します。propsをリアクティブに扱う場合はtoRefs
を使用して分割代入することで、コンポーネントの可読性と保守性を高めることができます。
これらのテクニックを活用することで、より明確で型安全なVueコンポーネントを作成することが可能になります。