Open3

v-date-pickerのアップデート実装メモ

redamoonredamoon

v-date-pickerのアップデートメモです。

  • 期間のrangeプロパティが未実装。。

https://github.com/vuetifyjs/vuetify/issues/18725

https://github.com/vuetifyjs/vuetify/milestone/74
第四クォーターで実装されるみたいですが、先が長い。。issueに変えているコードをラップして使う。

redamoonredamoon
<template>
  <div>
    <v-menu
      v-model="menu"
      :close-on-content-click="false"
      close-on-click
      transition="scale-transition"
      offset-y
    >
      <template v-slot:activator="{ props }">
        <v-btn v-bind="props" variant="flat" :text="dateRangeText">
          <template #append>
            <v-icon color="white"> mdi-calendar-blank </v-icon>
          </template>
        </v-btn>
      </template>

      <v-date-picker
        hide-header
        v-model="dates"
        class="datePicker mt-4"
        show-adjacent-months
        show-current
        scrollable
        rounded
        elevation="5"
        :max="new Date()"
      >
        <template #actions>
          <v-btn
            color="primary"
            variant="text"
            @click="cancel"
            :text="$t('cancel')"
          />
          <v-btn
            color="primary"
            variant="text"
            @click="save"
            :text="$t('ok')"
          />
        </template>
      </v-date-picker>
    </v-menu>
  </div>
</template>

<script setup lang="ts">
  import { computed, ref, unref } from "vue";

  const range = ref([]);
  const menu = ref(false);
  const model = defineModel<Date[]>();
  const dates = computed({
    get: datesBetween,
    set: updateRange,
  });

  const dateRangeText = computed(() => {
    if (model.value == undefined || model.value.length == 0) {
      return 'aaaa';
    }
    const [start, end] = unref(model);
    if (!!start && !!end) {
      return ` ${start.toLocaleDateString()}"
      )} ${end.toLocaleDateString()}`;
    } else if (isToday(start)) {
      return 'aaaadddd';
    } else {
      return start.toLocaleDateString();
    }
  });

  function updateRange(date) {
    const [start, end] = unref(range);
    //if everything is null or everything is not
    if (!!start === !!end) {
      range.value = [date];
    } else if (date < start) {
      range.value = [date, start];
    } else if (date > start) {
      range.value = [start, date];
    }
  }

  function datesBetween() {
    if (range.value == undefined) {
      return [];
    }
    const [start, end] = unref(range);
    if (!!start && !!end) {
      const between = [];
      const currentDate = new Date(start);
      while (currentDate <= end) {
        between.push(new Date(currentDate));
        currentDate.setDate(currentDate.getDate() + 1);
      }
      return between;
    } else {
      return range.value;
    }
  }

  function isToday(date) {
    const today = new Date(Date.now());
    today.setHours(0, 0, 0, 0);
    return today.getTime() == date.getTime();
  }

  function save() {
    model.value = range.value;
    menu.value = false;
  }

  function cancel() {
    range.value = model.value || [];
    menu.value = false;
  }
</script>

細かいことはなしとして、あとでStorybookに展開して確認する。プレイグランドではうごいた

redamoonredamoon

https://v2.vuetifyjs.com/ja/components/date-pickers/#range

Vuetify 2 で利用してた日付の範囲を選択できる range プロパティは、Vuetify 3 では未実装。
multiple には range で制御できるが取得する値が従来の [ "2019-09-10", "2019-09-27" ] のような値にはならず、選択したすべての値が配列に挿入される

Vuetify 3 では、multiple rangeは選択した値がすべて入る

サンプルを作った。
https://nuxt3-vuetify-storybook.pages.dev/?path=/story/components-vdatepickers--range

範囲を選択して、保存ボタンでロギングすると選択した値のすべて挿入される。

range プロパティ の実装は 今年の10月にはいるようです。
https://github.com/vuetifyjs/vuetify/milestone/74

現時点では、範囲を選択するようにラップして必要な範囲の配列になるようにしなければならない。(既存処理との兼ね合い)
範囲を選択できるサンプルを作った。

https://nuxt3-vuetify-storybook.pages.dev/?path=/story/components-vrecurringdatepickers--default