はじめに
Vuetifyには今の所、DatePickerとTimePickerしかなく、DateTimePickerが必要な人はnpmでDateTimePickerをインストールすることになる場合がほとんどだと思います。しかし、自由にインストールが出来ない環境だと手打ちになります。そんな環境に向けてソースを公開しておきます。
サンプル
See the Pen Untitled by nakai1980 (@nakai1980) on CodePen.
動作説明
日付テキストボックスをクリックで公式のDatePickerとTimePickerがタブ形式のアラートで開きます。OKかキャンセルをクリックしないと元の画面に戻れない形式となってます。
日付データの取得でデータ取得サンプルがデータを取ってきます。
ソース
呼び出し側
<template>
<v-app id="app">
<v-container class="grey lighten-5">
<v-row>
<v-spacer></v-spacer>
<v-col>
<date-time ref="getItem1"
:labelname="'test1'"
:datetime_value="datetime1"
></date-time>
</v-col>
<v-spacer></v-spacer>
<v-col>
<date-time ref="getItem2"
:labelname="'test2'"
:datetime_value="datetime2"
></date-time>
</v-col>
<v-spacer></v-spacer>
</v-row>
<v-card max-width="400" class="mx-auto">
<v-card-actions>
<v-btn v-on:click="onClick">日時データを取得</v-btn>
</v-card-actions>
<v-card-text>
子コンポーネントのdata1: {{message1}}
<br>子コンポーネントのdata2: {{message2}}
</v-card-text>
</v-card>
</v-container>
</v-app>
</template>
<script>
import Datetime from "./DateTime.vue";
export default {
name: "App",
components: {
'date-time': Datetime,
},
data() {
return {
message1: '',
message2: '',
datetime1: (new Date()).toISOString().substring(0, 10) + " " + "00:00",
datetime2: (new Date()).toISOString().substring(0, 10) + " " + "10:00",
}
},
methods:{
onClick(){
this.message1 = this.$refs.getItem1.datetime;
this.message2 = this.$refs.getItem2.datetime;
}
}
};
</script>
本体
<template>
<v-dialog
v-model="dialog"
ref="dialog"
:return-value.sync="datetime"
persistent
width="290px"
>
<template v-slot:activator="{ on, attrs }">
<v-text-field
prepend-icon="mdi-calendar"
:label="labelname"
:value="datetime_value"
v-model="datetime"
readonly
v-bind="attrs"
v-on="on"
@click="backupDateTime"
>{{ datetime }}</v-text-field>
</template>
<v-card class="child-flex" flat tile>
<v-tabs
v-model="currentItem"
fixed-tabs
>
<v-tab
key="calendar"
href="#tabs-calendar"
>
<v-icon>mdi-calendar</v-icon>
</v-tab>
<v-tab
key="alarm"
href="#tabs-alarm"
>
<v-icon>mdi-alarm</v-icon>
</v-tab>
</v-tabs>
<v-tabs-items v-model="currentItem">
<v-tab-item key="calendar" value="tabs-calendar">
<v-card>
<v-date-picker
v-model="date"
scrollable
locale="jp-ja"
:day-format="(date)=>new Date(date).getDate()"
>
<v-btn
text
color="primary"
@click="clearDialog"
>
Cancel
</v-btn>
<v-btn
text
color="primary"
@click="saveDialog"
>
OK
</v-btn>
</v-date-picker>
</v-card>
</v-tab-item>
<v-tab-item key="alarm" value="tabs-alarm">
<v-card>
<v-time-picker
v-model="time"
ampm-in-title
flat
scrollable
>
<v-btn
text
color="primary"
@click="clearDialog"
>
Cancel
</v-btn>
<v-btn
text
color="primary"
@click="saveDialog"
>
OK
</v-btn>
</v-time-picker>
</v-card>
</v-tab-item>
</v-tabs-items>
</v-card>
</v-dialog>
</template>
<script>
export default {
props:{
labelname: "",
datetime_value: "",
},
data () {
return {
currentItem: 'tabs-calendar',
dialog: false,
date: (this.datetime_value).substring(0, 10),
time: (this.datetime_value).substring(11, 15),
datetime: this.datetime_value,
datetime_old: "",
}
},
methods: {
saveDialog() {
this.currentItem = 'tabs-calendar';
this.$refs.dialog.save(this.datetime);
},
clearDialog() {
this.currentItem = 'tabs-calendar';
this.datetime = this.datetime_old;
const datetime_split = this.datetime.split(' ');
this.date = datetime_split[0];
this.time = datetime_split[1];
this.dialog = false;
},
backupDateTime() {
this.datetime_old = this.datetime;
}
},
watch: {
date: {
deep: true,
handler(value) {
this.datetime = value + " " + this.time;
}
},
time: {
deep: true,
handler(value) {
this.datetime = this.datetime.substring(0, 10) + " " + value;
}
},
}
}
</script>
<style scoped>
::v-deep .v-time-picker-title__time .v-picker__title__btn, ::v-deep .v-time-picker-title__time span {
height: 56px!important;
font-size: 56px!important;
}
::v-deep .v-time-picker-title {
line-height: 1.5;
}
::v-deep .v-picker__title {
justify-content: center!important;
display: inline-flex!important;
}
::v-deep .v-card > *:first-child:not(.v-btn):not(.v-chip):not(.v-avatar), .v-card > .v-card__progress + *:not(.v-btn):not(.v-chip):not(.v-avatar) {
border-top-left-radius: 0;
border-top-right-radius: 0;
}
::v-deep .v-tabs-slider-wrapper {
height: 3px!important;
color: #1599e7 !important;
}
::v-deep .v-date-picker-table th {
font-size: 15px;
}
::v-deep .v-date-picker-table .v-btn {
z-index: auto;
margin: 0;
font-size: 15px;
}
::v-deep .v-date-picker-table.v-date-picker-table--date
> table
> tbody
tr
td:nth-child(7)
.v-btn__content {
color: blue;
}
::v-deep .v-date-picker-table.v-date-picker-table--date
> table
> tbody
tr
td:nth-child(1)
.v-btn__content {
color: red;
}
</style>