You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:基于Vue.js 2开发移动端滚动式日期选择器

Vue.js 2 移动端滚动式日期选择器实现方案

针对你需要的滚轮式日期选择器(参考图:滚动式日期选择器),下面提供两种可行的实现思路:

一、自定义开发实现

如果找不到完全匹配的组件,自定义开发是最灵活的方式,核心要点如下:

1. 布局与滚动对齐

利用CSS的滚动捕捉特性,让每个日期选项滚动后自动居中,确保选中项始终在可视区域中间:

.date-picker-wrap {
  display: flex;
  justify-content: space-around;
  padding: 10px 0;
}
.date-column {
  width: 80px;
  height: 200px;
  overflow-y: auto;
  scroll-snap-type: y mandatory;
  -webkit-overflow-scrolling: touch; /* 优化iOS滚动流畅度 */
}
.date-item {
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  scroll-snap-align: center;
}
.date-item.active {
  color: #1890ff;
  font-weight: bold;
}

2. Vue组件核心逻辑

通过监听滚动事件,计算当前选中的日期项,并同步选中值:

<template>
  <div class="date-picker-wrap">
    <div 
      class="date-column" 
      ref="yearColumn"
      @scroll="handleScroll('year')"
    >
      <div 
        v-for="year in yearList" 
        :key="year"
        class="date-item"
        :class="{ active: selectedYear === year }"
      >
        {{ year }}年
      </div>
    </div>
    <div 
      class="date-column" 
      ref="monthColumn"
      @scroll="handleScroll('month')"
    >
      <div 
        v-for="month in monthList" 
        :key="month"
        class="date-item"
        :class="{ active: selectedMonth === month }"
      >
        {{ month }}月
      </div>
    </div>
    <div 
      class="date-column" 
      ref="dayColumn"
      @scroll="handleScroll('day')"
    >
      <div 
        v-for="day in dayList" 
        :key="day"
        class="date-item"
        :class="{ active: selectedDay === day }"
      >
        {{ day }}日
      </div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      selectedYear: new Date().getFullYear(),
      selectedMonth: new Date().getMonth() + 1,
      selectedDay: new Date().getDate(),
      yearList: [],
      monthList: Array.from({length:12}, (_,i) => i+1),
      dayList: []
    }
  },
  mounted() {
    // 生成近10年的年份列表
    const currentYear = new Date().getFullYear()
    this.yearList = Array.from({length:10}, (_,i) => currentYear - 5 + i)
    // 初始化日期列表
    this.updateDayList()
    // 滚动到默认选中项
    this.scrollToDefault()
  },
  watch: {
    selectedMonth() {
      this.updateDayList()
    },
    selectedYear() {
      this.updateDayList()
    }
  },
  methods: {
    updateDayList() {
      // 根据年月计算当月天数
      const days = new Date(this.selectedYear, this.selectedMonth, 0).getDate()
      this.dayList = Array.from({length:days}, (_,i) => i+1)
    },
    handleScroll(type) {
      const column = this.$refs[`${type}Column`]
      const itemHeight = 40 // 与CSS中.date-item的height一致
      // 计算当前居中的项索引
      const activeIndex = Math.round(column.scrollTop / itemHeight)
      // 更新选中值
      if (type === 'year') {
        this.selectedYear = this.yearList[activeIndex]
      } else if (type === 'month') {
        this.selectedMonth = this.monthList[activeIndex]
      } else if (type === 'day') {
        this.selectedDay = this.dayList[activeIndex]
      }
    },
    scrollToDefault() {
      // 滚动到默认选中项的位置
      const itemHeight = 40
      const yearIndex = this.yearList.indexOf(this.selectedYear)
      const monthIndex = this.monthList.indexOf(this.selectedMonth)
      const dayIndex = this.dayList.indexOf(this.selectedDay)
      
      this.$refs.yearColumn.scrollTop = yearIndex * itemHeight
      this.$refs.monthColumn.scrollTop = monthIndex * itemHeight
      this.$refs.dayColumn.scrollTop = dayIndex * itemHeight
    }
  }
}
</script>

二、基于现有组件改造

如果不想从零开发,可以用移动端UI组件库的滚轮选择器改造:

  • 比如Vant 2的Picker组件,支持多列选择,直接配置年、月、日三列的选项,即可快速实现滚轮式日期选择器,无需自己处理滚动逻辑和触摸适配。
  • 示例思路:将年、月、日作为Picker的三个列,通过columns属性动态生成选项,监听change事件同步选中值。

内容的提问来源于stack exchange,提问作者Leila Oliveira

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 21:12:52