TL;DR
- VuejsのUIフレームワークであるVuetifyを使っていい感じの誕生日入力フォームを作成する
- 以下を満たすものとする
- 日本語対応
- 日付の「日」は取る
- 年から選択
- 最初に年を選択するとき、1995年からになるようにする
- 日付範囲制限(未来や古すぎる日付を誕生日に設定できない)
- 日付を選択と同時にpickerを閉じる
動作環境
Vue.js v2.x
Vuetify v2.1.14
できたもの
解説
- 日本語対応
- v-date-pickerのlocaleプロパティを設定
- 日付の「日」は取る
- v-date-pickerのday-formatプロパティを設定
- 日付範囲制限(未来や古すぎる日付を誕生日に設定できない)
- max, minプロパティを設定
- 最初に年を選択するとき、1995年からになるようにする
- picker-dateプロパティを制御する必要がある
- picker-dateではpickerの値をコントロールできる
- そのため、v-modelでbindされたdateオブジェクトを触らずpickerについてのみ触ることができる
<v-date-picker
ref="picker"
locale="jp-ja"
v-model="date"
:day-format="date => new Date(date).getDate()"
:max="new Date().toISOString().substr(0, 10)"
:picker-date="pickerDate"
min="1950-01-01"
@change="save"
></v-date-picker>
- 年から選択
- v-menuにバインドしたmenuをwatchし、v-date-pickerのactivePickerを制御する。
- menuを選ばれたタイミングのみでactivePickerをYEAR指定にしないと、ずっと年選択になったりする
- 選び始めたらpickerDateを初期化しないと、ユーザが入力してもpickerDateの値になってしまうので注意
watch: {
menu (val) {
val && setTimeout(() => (
// 年から選ぶようにする
this.$refs.picker.activePicker = 'YEAR',
// 選び始めたら初期化
this.pickerDate = null
))
},
},
- 日付を選択と同時にpickerを閉じる
- 日付を選択したとき = v-date-pickerの
@change
が発火するタイミング - その際、pickerDateと選択したdateを同期させないと、もう一度誕生日を選びなおした時に前回の日付が初期値として機能してくれないので注意
- 日付を選択したとき = v-date-pickerの
methods: {
save (date) {
this.$refs.menu.save(date)
// 再入力に備えて、入力が終わったら同期する
this.pickerDate = date;
},
},
感想
v-date-pickerは抽象的な作りをしていて、開発者が用意されたプロパティやコンポーネントをよく調べる必要があります。
そのため、必然的にVueコンポーネントの学びを多く得られると思いました。
ぜひ、v-date-pickerもといVuetifyを触ってみてください!
付録
今回のコード
template
<div id="app">
<v-app id="inspire">
<v-menu
ref="menu"
v-model="menu"
:close-on-content-click="false"
transition="scale-transition"
offset-y
full-width
min-width="290px"
>
<template v-slot:activator="{ on }">
<v-text-field
v-model="date"
label="誕生日を入力"
prepend-icon="event"
readonly
v-on="on"
></v-text-field>
</template>
<v-date-picker
ref="picker"
locale="jp-ja"
v-model="date"
:day-format="date => new Date(date).getDate()"
:max="new Date().toISOString().substr(0, 10)"
:picker-date="pickerDate"
min="1950-01-01"
@change="save"
></v-date-picker>
</v-menu>
</v-app>
</div>
script
new Vue({
el: '#app',
vuetify: new Vuetify(),
data: () => ({
date: null,
menu: false,
// pickerの初期値(95年から年が選べるようになる)
pickerDate: '1995-1-1',
}),
watch: {
menu (val) {
val && setTimeout(() => (
// 年から選ぶようにする
this.$refs.picker.activePicker = 'YEAR',
// 選び始めたら初期化
this.pickerDate = null
))
},
},
methods: {
save (date) {
this.$refs.menu.save(date)
// 再入力に備えて、入力が終わったら同期する
this.pickerDate = date;
},
},
})