やりたいこと
- Vue.jsのカスタムコンポーネントにv-modelを渡して双方向バインディング
- VuetifyのDatePickerの「Picker in menu」の例をコンポーネント化したい
要点
要点というか今になってようやくv-model
が「何をするシンタックスシュガーなのか」を理解しただけなのですが、カスタムコンポーネント側が以下の要件を満たせばOKみたいです。
カスタムコンポーネント側が$data.hoge
で状態を持つと仮定して、
サンプル
DatePickerMenu.vue ※Vuetify依存です
<template> <v-menu ref="menu" v-model="opened" :close-on-content-click="false" :nudge-right="40" :return-value.sync="date" lazy transition="scale-transition" offset-y full-width min-width="290px" > <template v-slot:activator="{ on }"> <v-text-field v-model="date" :label="label" prepend-icon="event" readonly v-on="on" /> </template> <v-date-picker v-model="date" no-title scrollable> <v-spacer /> <v-btn flat @click="opened = false"> キャンセル </v-btn> <v-btn flat color="primary" @click="$refs.menu.save(date)"> OK </v-btn> </v-date-picker> </v-menu> </template> <script> export default { name: 'DatePickerMenu', props: { label: { type: String, default: '日付' }, value: { type: String, default: () => new Date().toISOString().substr(0, 10) } }, data () { return { opened: false, date: this.value } }, watch: { value (val) { this.date = val }, date (val) { this.$emit('input', val) } } } </script>
Sample.vue
<template> <div> <h3>期間</h3> <date-picker-menu v-model="dateFrom" label="この日から" /> <date-picker-menu v-model="dateTo" label="この日まで" /> </div> </template> <script> import DatePickerMenu from '@/components/DatePickerMenu' export default { components: { DatePickerMenu }, data () { // fromの初期値は1週間前 let dateFrom = new Date() dateFrom.setDate(dateFrom.getDate() - 7) let dateTo = new Date() return { dateFrom: dateFrom.toISOString().substr(0, 10), dateTo: dateTo.toISOString().substr(0, 10) } }, watch: { dateFrom () { console.log('dateFrom', this.dateFrom) }, dateTo () { console.log('dateTo', this.dateTo) } } } </script>