親から子へのデータ渡し
v-model を使用したデータのバインディング
Vue 3 では、v-model
を使用して親コンポーネントから子コンポーネントにデータを渡し、双方向データバインディングを実現できます。デフォルトでは v-model
は modelValue
を渡しますが、カスタムプロパティ名を使用することも可能です。
<template>
<ConfirmDeleteDialog v-model:visible="dialog" @confirm="goToCustomerDelete" />
</template>
<script setup>
import { ref } from 'vue';
const dialog = ref(false);
const goToCustomerDelete = () => {
console.log("削除を実行しました。");
};
</script>
上記では、dialog
という親コンポーネントのデータが子コンポーネントに渡され、さらに子コンポーネントがデータを更新することで親の状態も変更されます。
<script setup lang="ts">
import { ref, watch } from 'vue';
interface Props {
visible: boolean;
}
const props = defineProps<Props>();
const emit = defineEmits<{
(event: "update:visible", value: boolean): void;
(event: "confirm"): void;
}>();
const localVisible = ref(props.visible);
watch(() => props.visible, (newVal) => {
localVisible.value = newVal;
});
const closeDialog = () => {
emit("update:visible", false);
};
const confirmDelete = () => {
emit("confirm");
closeDialog();
};
</script>
<template>
<v-dialog v-model="localVisible" max-width="400px">
<v-card>
<v-card-title class="text-h6">本当に削除しますか?</v-card-title>
<v-card-text>この操作は元に戻せません。</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn @click="closeDialog">キャンセル</v-btn>
<v-btn color="red-darken-1" class="text-none" variant="flat" @click="confirmDelete">削除</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
解説
props
によるデータ受け取り- 親コンポーネントから渡された
dialog
は、props.visible
として受け取ります。
- 親コンポーネントから渡された
emit
によるデータ更新- 子コンポーネントで
emit("update:visible", 値)
を発火することで、親コンポーネントのデータを更新します。
- 子コンポーネントで
- ローカル状態の管理
localVisible
を使用してローカルの状態を管理し、watch
でprops.visible
の変更を反映しています。
子から親へのデータ送信
update:<プロパティ名>
のイベント
v-model
を使用する場合、子コンポーネントは update:<プロパティ名>
イベントを発火させる必要があります。これにより、親コンポーネントのデータが更新されます。
<ConfirmDeleteDialog v-model:visible="dialog" @confirm="goToCustomerDelete" />
const emit = defineEmits<{
(event: "update:visible", value: boolean): void;
(event: "confirm"): void;
}>();
const closeDialog = () => {
emit("update:visible", false);
};
defineEmits
とイベントの型定義
defineEmits
は、子コンポーネントから親コンポーネントへイベントを通知するために使用します。TypeScript を使用する場合、イベント名や引数の型を明示的に定義できます。
型定義の例
const emit = defineEmits<{
(event: "update:visible", value: boolean): void;
(event: "confirm"): void;
}>();
解説
(event: "update:visible", value: boolean): void;
update:visible
イベントには、boolean
型の引数value
を渡す必要があることを示しています。
(event: "confirm"): void;
confirm
イベントは引数を必要としないことを示しています。
emit("update:visible", true); // `update:visible` を発火し、true を渡す
emit("confirm"); // `confirm` を発火する
まとめ
- 親から子へデータを渡す際は、
props
を使用します。 - 親から子への双方向バインディングには、
v-model
とupdate:<プロパティ名>
を組み合わせます。 - 子から親への通知は、
emit
を使用します。 defineEmits
を用いることで、イベントの型を明示的に定義し、コードの可読性と安全性を向上させます。