Vue2については「Vue/Vuetify ダイアログの設置と親子コンポーネント間のデータ送受信」で書いたが、Vue3では書き方が違うのでまとめておく。また、子コンポーネントとしてVuetify3(beta)の確認ダイアログを使用して動作を確認しておく。
目次
基本
Vue3における親子コンポーネント間データ受け渡しの仕組み。(<script setup>構文)
親コンポーネントから子コンポーネントへの送受信
親コンポーネントからの送信
親コンポーネントからはプロパティとしてv-bindディレクティブ「:」でデータを渡すことができる。
<child-component :parentProp="parentData">
子コンポーネントでの受信
子コンポーネントはプロパティとしてデータを受信
<script setup>
…
const props = defineProps({
parentProp: String,
})
const parentData = ref(props.parentProp)
…
</script>
子コンポーネントから親コンポーネントへの送受信
子コンポーネントからの送信
子コンポーネントでEmitを定義
emit(親コンポーネントのイベント名, 送信データ)
定義したEmitを実行することで指定した親コンポーネントのイベントが発火
<script setup>
…
const emit = defineEmits(['eventEmit'])
const execEmit = () => {
emit('eventEmit', { 'response': "Child to Parent" })
}
…
</script>
親コンポーネントでの受信
親コンポーネントではv-onディレクティブ「@」で子コンポーネントで定義したEmitのイベントが発火したときのメソッドを定義すると、引数として子コンポーネントで定義したEmitの送信データを受信できる。
<child-component @eventEmit="updateEvent" />
<script setup>
…
const childData = ref('')
const updateEvent = (data) => {
childData.value = data.response
}
…
</script>
親子コンポーネントで同期するならcomputed
<script setup>
…
const props = defineProps(['parentProp'])
const parent = computed(() => {
return props.parentProp
})
…
</script>
確認ダイアログを子コンポーネントとした設定例(<script setup>構文)
Vuetify3(beta)の確認ダイアログを利用した親子コンポーネント間データ送受信で動作を<script setup>構文で確認してみる。
開発環境
vue v3.2.40
Vuetify3(Beta)
ファイル構成
components
┣ Share
┃ ┗ Confirm.vue
┗ Test.vue
親コンポーネント
<template>
<h1>Test</h1>
<confirm-dialog :confirmText="message" @eventEmit="execEvent"></confirm-dialog>
<p>{{ response }}</p>
</template>
<script setup>
import { ref } from 'vue'
import ConfirmDialog from './Share/Confirm.vue'
const message = ref("よろしいですか?")
const response = ref("")
const execEvent = (data) => {
response.value = data.message
}
</script>
子コンポーネント(Dialog)
<template>
<v-btn
color="primary"
@click = "dialog = true"
>
確認
</v-btn>
<v-dialog
v-model="dialog"
max-width="500px"
>
<v-card>
<v-card-text>
{{ agreement }}
</v-card-text>
<v-card-actions>
<v-btn variant="outlined" @click="dialog = false">Cancel</v-btn>
<v-btn variant="outlined" color="success" @click="execEmit(true)">OK</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script setup>
import { ref } from 'vue'
const props = defineProps({
confirmText: String,
})
const dialog = ref(false)
const agreement = props.confirmText
const emit = defineEmits(['eventEmit'])
const execEmit = () => {
emit('eventEmit', { 'result': true, 'message': "確認しました"})
dialog.value = false
}
</script>
確認ダイアログを子コンポーネントとした設定例(通常構文)
上記では<script setup>構文で記述しているがVue3通常構文では書き方が異なるので一応記載しておく。
親コンポーネント
<template>
<h1>Sample</h1>
<confirm-dialog :confirmText="message" @eventEmit="execEvent"></confirm-dialog>
<p>{{ response }}</p>
</template>
<script>
import { defineComponent,ref } from 'vue'
import ConfirmDialog from './Share/Confirm2.vue'
export default defineComponent({
components: {
ConfirmDialog,
},
setup() {
const message = ref("よろしいですか?")
const response = ref("")
const execEvent = (data) => {
response.value = data.message
}
return {
message,
response,
execEvent,
}
}
})
</script>
子コンポーネント(Dialog)
<template>
<v-btn
color="primary"
@click = "dialog = true"
>
確認
</v-btn>
<v-dialog
v-model="dialog"
max-width="500px"
>
<v-card>
<v-card-text>
{{ agreement }}
</v-card-text>
<v-card-actions>
<v-btn variant="outlined" @click="dialog = false">Cancel</v-btn>
<v-btn variant="outlined" color="success" @click="execEmit(true)">OK</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
<script>
import { ref, defineComponent } from 'vue'
export default defineComponent({
props: {
confirmText: {
type: String,
}
},
emits: ['eventEmit'],
setup(props, context) {
const dialog = ref(false)
const agreement = props.confirmText
const execEmit = () => {
context.emit('eventEmit', { 'result': true, 'message': "確認しました"})
dialog.value = false
}
return {
dialog,
agreement,
execEmit
}
}
})
</script>