当前位置 : 主页 > 网络编程 > 其它编程 >

Vue 中如何实现日期范围选择器?

来源:互联网 收集:自由互联 发布时间:2023-08-02
Vue 中如何实现日期范围选择器? 日期范围选择器是现代 Web 应用程序中经常用到的一种界面组件。它允许用户从一个日期范围中选择一个日期或者一个时间段。对于需求为日期范围选择

Vue 中如何实现日期范围选择器?

日期范围选择器是现代 Web 应用程序中经常用到的一种界面组件。它允许用户从一个日期范围中选择一个日期或者一个时间段。对于需求为日期范围选择器的 Web 应用程序开发,Vue.js 是一个非常好的选择。

Vue.js 是一个用于构建用户界面的渐进式 JavaScript 框架,它允许开发者使用组件化的方式来构建复杂的交互式界面。在这篇文章中,我们将介绍如何使用 Vue.js 来创建一个日期范围选择器组件。

  1. 组件结构

首先,让我们来定义一下组件的结构。我们需要一个包含两个选择器的容器,一个用于选择开始日期,另一个用于选择结束日期。这两个选择器都应该包括一个日历组件和一个输入框,用户可以在输入框中直接输入日期,也可以通过日历选择器来选择日期。

在 Vue 中,组件通常采用树形结构来组织,我们可以定义一个父组件,然后将两个日期选择器组件作为它的子组件。父组件负责管理数据,子组件负责展示数据和与用户交互。代码如下:

<template>
  <div>
    <date-selector v-model="startDate"></date-selector>
    <date-selector v-model="endDate"></date-selector>
  </div>
</template>

<script>
import DateSelector from './DateSelector.vue'

export default {
  components: {
    DateSelector
  },
  data () {
    return {
      startDate: '',
      endDate: ''
    }
  }
}
</script>
  1. 日历组件

接下来,让我们来实现日历组件。这个组件将允许用户在一个日历中选择日期,并将选择的日期显示在输入框中。我们可以使用 Vue.js 的 v-model 指令来实现输入框和数据绑定。代码如下:

<template>
  <div class="date-selector">
    <input :value="dateString" @blur="handleChange" @keydown.enter="handleChange">
    <svg @click="showCalendar" class="icon icon-calendar">
      <use xlink:href="#calendar" />
    </svg>
    <div v-if="show" class="date-calendar">
      <calendar :date="date" @change="updateDate"></calendar>
    </div>
  </div>
</template>

<script>
import Calendar from './Calendar.vue'

export default {
  components: {
    Calendar
  },
  props: {
    value: {
      type: String,
      default: ''
    }
  },
  data () {
    return {
      date: new Date(),
      show: false
    }
  },
  computed: {
    dateString () {
      return this.value || ''
    }
  },
  methods: {
    handleChange (event) {
      const dateString = event.target.value.trim()
      if (dateString) {
        const date = new Date(dateString)
        if (!isNaN(date.getTime())) {
          this.date = date
        }
      }
      this.$emit('input', dateString)
    },
    showCalendar () {
      this.show = true
    },
    updateDate (date) {
      this.date = date
      this.show = false
      this.$emit('input', this.date.toISOString().slice(0, 10))
    }
  }
}
</script>

可以看到,这个组件包含一个输入框和一个表示日历的 SVG 图标。用户点击 SVG 图标时,将会显示一个日历组件。在日历组件中选择日期后,日期范围选择器将更新数据,并将日期字符串传递到父组件中。

  1. 日历组件的核心 - 日历显示和交互

最后,让我们来实现一个日历组件。由于我们的目标是实现一个日期范围选择器,因此我们将仅实现日期选择,并将禁用时间选择。我们将使用 HTML 的 table 元素来构建日历,使用 CSS 来实现样式。代码如下:

<template>
  <div class="calendar">
    <div class="calendar-header">
      <button class="calendar-btn" @click.prevent="prevMonth">&lt;</button>
      <span class="calendar-month">{{month}} {{year}}</span>
      <button class="calendar-btn" @click.prevent="nextMonth">&gt;</button>
    </div>
    <table>
      <thead>
        <tr>
          <th>Sun</th>
          <th>Mon</th>
          <th>Tue</th>
          <th>Wed</th>
          <th>Thu</th>
          <th>Fri</th>
          <th>Sat</th>
        </tr>
      </thead>
      <tbody>
        <tr v-for="week in weeks" :key="week">
          <td v-for="date in week" :key="date" @click.prevent="updateDate(date)">
            <div :class="{ 'calendar-date': true, 'calendar-date--selected': isDateSelected(date), 'calendar-date--disabled': isDateDisabled(date) }">{{date.getDate()}}</div>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
</template>

<script>
export default {
  props: {
    date: Date
  },
  data () {
    return {
      year: this.date.getFullYear(),
      month: this.date.toLocaleString('default', { month: 'long' }),
      selectedDate: this.date
    }
  },
  computed: {
    weeks () {
      const weeks = []
      const firstDayOfMonth = new Date(this.year, this.date.getMonth(), 1)
      const lastDayOfMonth = new Date(this.year, this.date.getMonth() + 1, 0)
      const daysInMonth = lastDayOfMonth.getDate()
      const firstDayOfWeek = firstDayOfMonth.getDay()
      let week = []
      for (let i = 0; i < firstDayOfWeek; i++) {
        week.push(new Date(this.year, this.date.getMonth(), i - firstDayOfWeek + 1))
      }
      for (let i = 1; i <= daysInMonth; i++) {
        week.push(new Date(this.year, this.date.getMonth(), i))
        if (week.length === 7) {
          weeks.push(week)
          week = []
        }
      }
      if (week.length > 0) {
        for (let i = week.length; i < 7; i++) {
          week.push(new Date(this.year, this.date.getMonth() + 1, i - firstDayOfWeek + 1))
        }
        weeks.push(week)
      }
      return weeks
    }
  },
  methods: {
    prevMonth () {
      if (this.date.getMonth() === 0) {
        this.year--
        this.month = 'December'
      } else {
        this.month = this.date.toLocaleString('default', { month: 'long', monthIndex: 'numeric' })
      }
      this.date.setMonth(this.date.getMonth() - 1)
    },
    nextMonth () {
      if (this.date.getMonth() === 11) {
        this.year++
        this.month = 'January'
      } else {
        this.month = this.date.toLocaleString('default', { month: 'long' })
      }
      this.date.setMonth(this.date.getMonth() + 1)
    },
    isDateSelected (date) {
      return date.toDateString() === this.selectedDate.toDateString()
    },
    isDateDisabled (date) {
      return date.getMonth() !== this.date.getMonth()
    },
    updateDate (date) {
      if (!this.isDateDisabled(date)) {
        this.selectedDate = date
        this.$emit('change', date)
      }
    }
  }
}
</script>

可以看到,这段代码包含一个计算属性 weeks,它是一个数组,每个数组元素代表一个星期。对于每个星期,我们使用 v-for 指令来构建日期单元格。我们通过 isDateSelected 和 isDateDisabled 方法来确定日期是否被选择或被禁用。同时,我们使用 updateDate 方法来更新日期并通知父组件这个事件。

至此,我们已经完成了 Vue.js 中的日期范围选择器组件。这个组件支持语言环境并允许用户选择日期范围,可以方便地应用于各种应用程序中。

网友评论