#vue2 #vue3
内部で別のComponentにbindしたい場合は、直接`props`を指定できないので`State`を使う。しかし、Componentの`props`に変更があった場合はそれを`State`に伝播できない。そのため、`watch`を使う必要がある。
以下のように利用できる`date-time-picker`モジュールを考える。
```vue
<date-time-picker :date-time.sync="state.date" />
```
コードは以下のようになる。
```vue
<template>
<div class="d-flex">
<v-menu
v-model="state.dateMenu"
:close-on-content-click="false"
offset-y
min-width="auto"
>
<template #activator="{ on, attrs }">
<v-text-field
:value="state.displayDate"
label="日付"
prepend-icon="mdi-calendar"
readonly
v-bind="attrs"
style="width: 120px"
v-on="on"
></v-text-field>
</template>
<v-date-picker
v-model="state.displayDate"
no-title
scrollable
color="cyan darken-1"
@change="changeDate"
/>
</v-menu>
<v-menu
v-model="state.timeMenu"
:close-on-content-click="false"
offset-y
min-width="auto"
>
<template #activator="{ on, attrs }">
<v-text-field
:value="state.displayTime"
label="時間"
prepend-icon="mdi-clock"
readonly
v-bind="attrs"
class="ml-3"
style="width: 80px"
v-on="on"
></v-text-field>
</template>
<v-time-picker
v-model="state.displayTime"
format="24hr"
color="cyan darken-1"
@change="changeTime"
></v-time-picker>
</v-menu>
</div>
</template>
<script lang="ts">
import { defineComponent, reactive, watch } from '@vue/composition-api'
import { DateTime } from 'owlelia'
import { Nullable } from '~/utils/types'
export default defineComponent({
props: {
dateTime: { type: Object as () => Nullable<DateTime>, default: null },
},
setup(props, { emit }) {
const state = reactive({
displayDate: '',
displayTime: '',
dateMenu: false,
timeMenu: false,
})
watch(
() => props.dateTime,
(_) => {
state.displayDate = props.dateTime?.displayDate ?? ''
state.displayTime = props.dateTime?.displayTime ?? ''
},
// immediate: trueを指定して、初期化のときにstateを更新する
{ immediate: true }
)
const changeDate = (date: string) => {
emit('update:dateTime', DateTime.of(`${date} ${state.displayTime}`))
}
const changeTime = (time: string) => {
emit('update:dateTime', DateTime.of(`${state.displayDate} ${time}`))
}
return {
state,
changeDate,
changeTime,
}
},
})
</script>
```
`watch`の書き方は[[Composition APIでwatch]]を参照。
ソースコードは[[vue2-typescript-vuetify-ie11-cms]]の`DateTimePicker.vue`を参照。