VDatePicker 変更点(Vuetify 2 〜 Vuetify 3 アップデート)
Vuetify 3 になって、VDatePicker
が Vuetify 2
から変更点があります。
長くVuetify 3でLabs状態だった機能が去年正式にリリースされました。
しかし、新しい VDatePicker
は、 Vuetify 2 と、Vuetify 3 で変更点が多く書き換えが多く発生している状態です。
Usage
API
Vuetify 2 Usage
Vuetify 2 API
VDatePicker
の変更点
Vuetify 2 から Vuetify 3 の Range 機能がない
Vuetify 2ではあった、Rangeプロパティがなくなりました。
代わりに、 multiple プロパティにRangeが追加されました。
range prop で日付の範囲を選択できます。 range プロパティを使用する場合、モデルは長さ2または空の配列であると想定します。
Vuetify 2では、2019-09-10 ~ 2019-09-20
のような値で表示できました。
値は、期間として model: [ "2019-09-10", "2019-09-20" ]
という配列の形式でstart end をセットされていました。
2019-09-10 ~ 2019-09-20
model: [ "2019-09-10", "2019-09-20" ]
Vuetify 3 の multiple プロパティの Rangeでは選択された期間のすべての日時(Date)がセットされるようになりました。
Vuetify 2では yyyy-MM-dd
の形式で表示されていましたが、Vuetify 3 では Date
の形式で表示されるようになりました。
[Sat Apr 06 2024 00:00:00 GMT+0900 (日本標準時), Sun Apr 07 2024 00:00:00 GMT+0900 (日本標準時), Mon Apr 08 2024 23:59:59 GMT+0900 (日本標準時)]
期間の選択を利用している場合は、日付をフォーマットをかけて、StartとEndの日付だけを抜き出した値に変更する必要があります。
サンプルコードでは、date-fns を利用して、日付のフォーマット行い startDate
と endDate
にセットしています。
import { format } from 'date-fns'
// ...
const emits = defineEmits<{
'update:modelValue': [value: string[]]
}>()
const onSave = () => {
if (!Array.isArray(dateValue.value)) {
dateValue.value = [dateValue.value]
}
const dates = dateValue.value.map(date => format(date, 'yyyy-MM-dd'))
const startDate = dates.at(0)
const endDate = dates.at(-1)
if (startDate !== undefined && endDate !== undefined) {
if (!props.multiple) {
emits('update:modelValue', [startDate])
} else {
emits('update:modelValue', [startDate, endDate])
}
}
}
加工することで、startとendの日付を取得することができます。
multiple プロパティはどこから選択しても、一番日付が古い日付がstart、一番新しい日付がendになるようになっています。
["2024-05-01", "2024-05-23"]
サンプルコード
OneDayの場合は、取得する値がDate形式になります。
コンポーネントでラップしてる場合、複数選択・期間選択ともに配列と揃えたほうが使いやすいことで加工しました。
dateValueにセットされた値が配列でなければ、dateValueを配列して格納します。
if (!Array.isArray(dateValue.value)) {
dateValue.value = [dateValue.value]
}
startDate
と endDate
が未定義の場合は更新しないようして、 props.multiple
が false
のときは startDateをセットします。
props.multiple
は、boolean
と range
の2つの値を取ります。
const startDate = dates.at(0)
と const endDate = dates.at(-1)
で、配列の最初と最後の値を取得しています。
そのためOneDayは、1個のみ選択されるため、同日がstartとendになります。
if (startDate !== undefined && endDate !== undefined) {
if (!props.multiple) {
emits('update:modelValue', [startDate])
} else {
emits('update:modelValue', [startDate, endDate])
}
}
サンプルコード
header / hide-header / actions / weekdays
header はセレクトした部分をカスタマイズできる
propsで受け渡すことができます。
<v-date-picker :header="props.header" />
templateで記述することで独自のHTMLを挿入することができます。
<template v-if="props.header" #header>
<v-card-title>
{{ props.header }}
</v-card-title>
</template>
デフォルトでUIが変更されて、Vuetify 3からヘッダーが追加されるようになりました。
選択した日付が表示されます。
hide-header でヘッダーを非表示にできる
hide-header
に真偽値を渡すことで表示制御を行えます。
actions でフッター部分をカスタマイズできる
Vuetify 2では ボタンなどは date-picker の外で定義していました。
Vuetify 3から、<template #actions></template>
のslotを利用できるようになりました。
これによって、datepicker内のslotでボタンを設置することができます。
<template v-if="isActions" #actions>
<v-btn color="info" label="クリア" @click="onClear">
クリア
</v-btn>
<v-btn color="primary" label="保存" @click="onSave">
保存
</v-btn>
</template>
曜日の表示制御は、show-week
から hide-weekdays
に変更されました。
まとめ
Vuetify 3 からComposition APIの対応をしつつ、従来のOptions API を変更したため、thisではなくrefで調整していく作業が発生していました。
このあたりが情報が少ないこともあり、手探りでドキュメントを読みながら意図した挙動(既存の動き)を再現していく必要がありました。
例えば、時間を組み合わせたパターンの場合、従来の書き方では行えません。(thisを利用した加工)
formatをかけつつ、時間などを組み合わせて意図した値を emitする必要していく必要があります。
時間を組み合わせたパターンは別記事で紹介したいと思います。
Discussion