返回

vue3.2.21封装一个优雅实用的日期时间选择器组件

前端

身处数据时代,时刻离不开时间。时间选择器是前端开发中常遇的组件,它方便用户从日历中选择日期或从时钟中选择时间。虽然市面上有许多现成的日期时间选择器库,但自己动手封装一个符合自身需求的组件也是一种学习和提升的过程。本文将手把手带领大家基于Vue3.2.21和dayjs库封装一个优雅实用的日期时间选择器组件,并提供一份详细的实现指南,让你快速上手。

封装日期时间选择器组件需要以下步骤:

  1. 创建一个Vue组件,作为日期时间选择器的根组件。
  2. 使用dayjs库处理日期和时间操作。
  3. 设计组件的UI界面,包括日历和时钟。
  4. 实现组件的交互逻辑,如日期和时间的选择。
  5. 提供必要的属性和事件,以便在父组件中使用。

代码实现如下:

<script>
import dayjs from 'dayjs';
export default {
  name: 'DateTimeSelector',
  props: {
    value: {
      type: [String, Date],
      default: null,
    },
    type: {
      type: String,
      default: 'datetime',
      validator: (value) => ['date', 'time', 'datetime'].includes(value),
    },
  },
  data() {
    return {
      isOpen: false,
      selectedDate: dayjs(),
      selectedTime: dayjs(),
    };
  },
  computed: {
    formattedValue() {
      if (!this.value) return '';
      return this.type === 'date' ? dayjs(this.value).format('YYYY-MM-DD') : dayjs(this.value).format('YYYY-MM-DD HH:mm:ss');
    },
  },
  methods: {
    open() {
      this.isOpen = true;
    },
    close() {
      this.isOpen = false;
    },
    selectDate(date) {
      this.selectedDate = date;
      if (this.type === 'date') {
        this.emitValue(dayjs(this.selectedDate).format('YYYY-MM-DD'));
      }
    },
    selectTime(time) {
      this.selectedTime = time;
      if (this.type === 'time') {
        this.emitValue(dayjs(this.selectedTime).format('HH:mm:ss'));
      } else if (this.type === 'datetime') {
        this.emitValue(dayjs(this.selectedDate).format('YYYY-MM-DD') + ' ' + dayjs(this.selectedTime).format('HH:mm:ss'));
      }
    },
    emitValue(value) {
      this.$emit('input', value);
    },
  },
};
</script>

组件的UI界面同样重要。本文参考了Element UI的样式,设计了一个简洁大方的日历和时钟界面。日历部分采用网格布局,每格代表一天,用户可以直观地选择日期。时钟部分采用圆形设计,用户可以通过拖动时针和分针来选择时间。

<template>
  <div class="date-time-selector">
    <div class="calendar-wrapper" v-show="isOpen && type.includes('date')">
      <div class="calendar-header">
        <span class="prev-month" @click="selectedDate = selectedDate.subtract(1, 'month')">&lt;</span>
        <span class="month-year">{{ selectedDate.format('YYYY-MM') }}</span>
        <span class="next-month" @click="selectedDate = selectedDate.add(1, 'month')">&gt;</span>
      </div>
      <div class="calendar-body">
        <div class="week-days">
          <span></span>
          <span></span>
          <span></span>
          <span></span>
          <span></span>
          <span></span>
          <span></span>
        </div>
        <div class="days">
          <span v-for="day in getDaysOfMonth(selectedDate)" :key="day" :class="{ 'disabled': !isDateEnabled(day) }" @click="selectDate(day)">{{ day.date() }}</span>
        </div>
      </div>
    </div>
    <div class="time-wrapper" v-show="isOpen && type.includes('time')">
      <div class="time-picker">
        <div class="clock-face">
          <div class="hour-hand" :style="{ transform: 'rotate(' + (selectedTime.hour() * 30 + selectedTime.minute() / 2) + 'deg)' }"></div>
          <div class="minute-hand" :style="{ transform: 'rotate(' + (selectedTime.minute() * 6) + 'deg)' }"></div>
        </div>
        <div class="time-input">
          <input type="number" min="0" max="23" v-model.number="selectedTime.hour()" />:
          <input type="number" min="0" max="59" v-model.number="selectedTime.minute()" />
        </div>
      </div>
    </div>
    <div class="actions" v-show="isOpen">
      <button type="button" @click="close">取消</button>
      <button type="button" @click="selectTime(selectedTime)">确定</button>
    </div>
  </div>
</template>

封装好的日期时间选择器组件可以在Vue应用中灵活使用。例如:

<template>
  <div>
    <date-time-selector v-model="date" type="date" @input="handleDateChange" />
    <date-time-selector v-model="time" type="time" @input="handleTimeChange" />
    <date-time-selector v-model="datetime" type="datetime" @input="handleDatetimeChange" />
  </div>
</template>

<script>
import DateTimeSelector from './DateTimeSelector.vue';
export default {
  components: { DateTimeSelector },
  data() {
    return {
      date: null,
      time: null,
      datetime: null,
    };
  },
  methods: {
    handleDateChange(date) {
      this.date = date;
    },
    handleTimeChange(time) {
      this.time = time;
    },
    handleDatetimeChange(datetime) {
      this.datetime = datetime;
    },
  },
};
</script>

本文详细介绍了如何基于Vue3.2.21和dayjs库封装一个日期时间选择器组件。该组件不仅功能完善,而且界面优雅实用,可以很好地满足开发需求。通过本文的学习,相信大家对日期时间选择器的封装有了更深入的理解。希望这篇文章能给广大开发者带来启发和帮助。