news 2026/9/19 19:58:39

Vuetify 月份选择器(VDatePicker type=“month“)完全指南:从基础用法到进阶实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Vuetify 月份选择器(VDatePicker type=“month“)完全指南:从基础用法到进阶实战

Vuetify 月份选择器(VDatePicker type="month")完全指南:从基础用法到进阶实战

【免费下载链接】vuetify🐉 Vue Component Framework项目地址: https://gitcode.com/gh_mirrors/vu/vuetify

导读

本文聚焦 Vuetify 中v-date-picker组件以type="month"形态运行时的月份选择能力。作为独立的月份选择器界面,它允许用户单独选择月份,或同时选择月份与年份,是构建报表筛选、账期选择、订阅周期管理等场景的高频组件。读完本文,你将掌握月份选择器的两种朝向配置、allowed-months 等核心 prop 的三种传参方式、与v-text-field集成的 Dialog/Menu 组合方案,以及多选、国际化、只读等进阶用法,并了解其底层源码(VDatePicker.tsx、VDatePickerMonths.tsx)是如何支撑这些行为的。

一、月份选择器是什么

在 Vuetify 中,v-date-picker是一个全能型日期选择组件,通过切换type属性可以在三种模式间流转:

  • type="date"(默认):完整日期(日、月、年)选择;
  • type="month":月份选择,即本文主题;
  • type="year":年份选择。

当设置type="month"时,组件渲染为独立的月份选择器。从源码结构看(VDatePicker.tsx),VDatePicker内部实际上是一个组合式容器:它将 VDatePickerControls(顶部年月导航控件)、VDatePickerHeader(头部标题区)、VDatePickerMonths(12 个月份网格)与 VDatePickerYears(年份列表)按viewMode切换渲染。当用户点击年份控件时,视图会切换到年份列表;点击月份后切回月份网格。月份网格本身由VDatePickerMonths承担,它基于createRange(12)生成 12 个按钮,并通过useGridSelection提供键盘方向键导航与data-v-month网格定位。

注意:本文档对应仓库中的packages/docs/src/pages/en/components/date-pickers-month.md,在 docs 源码中该页面标记为disabled: true(date-pickers-month.md),但这不影响其示例与组件行为在源码仓库中的可用性,所有示例文件均存在于 v-date-picker-month 目录下。

二、基础用法(Usage)

月份选择器有 portrait(竖版,默认)和 landscape(横版)两种朝向。最简单的用法如下:

<template> <v-row class="justify-center"> <v-date-picker v-model="picker" type="month" ></v-date-picker> </v-row> </template> <script> export default { data () { return { picker: (new Date(Date.now() - (new Date()).getTimezoneOffset() * 60000)).toISOString().substr(0, 10), } }, } </script>

对应示例文件:usage.vue。

几点需要说明:

  • model 值格式:月份选择器的v-model接受YYYY-MM形式的月份字符串(如'2017-12'),示例中为了统一演示,初始值用 ISO 字符串截取得到。请以实际业务需要的YYYY-MM字符串为准。
  • 默认选中:若不给v-model赋值,从源码看(VDatePickerMonths.tsx 中的watchEffect),内部会用adapter.getMonth(adapter.date())将模型回填为当前月份。
  • 朝向切换:通过landscapeprop 切换为横版布局,横版下头部会显示在侧边。相关示例见 misc-orientation.vue:
<v-date-picker v-model="picker" :landscape="landscape" type="month" ></v-date-picker>

三、核心 Props 详解

月份选择器继承自VDatePicker的整套 props(定义于 VDatePicker.tsx),下面按文档示例逐一展开。

3.1 Allowed months:限定可选月份

allowed-datesprop 可以限制可选择的月份,支持三种传参形式:

  1. 数组:显式列出允许的日期字符串;
  2. 对象:以日期为键、布尔值为值的映射;
  3. 函数:接收日期字符串,返回布尔值,true表示允许选择。

官方示例(prop-allowed-months.vue)配合min/max使用,函数形式只允许偶数月:

<template> <v-row class="justify-center"> <v-date-picker v-model="date" :allowed-dates="allowedMonths" class="mt-4" max="2019-10" min="2017-06" type="month" ></v-date-picker> </v-row> </template> <script> export default { data () { return { date: '2017-12', } }, methods: { // 只允许选择偶数月份 allowedMonths: val => parseInt(val.split('-')[1], 10) % 2 === 0, }, } </script>

提示:min="2017-06"max="2019-10"在这里同样接受YYYY-MM格式的月份字符串作为边界。

源码侧佐证VDatePicker会把allowed-dates解析为allowedMonths计算属性(见 VDatePicker.tsx 与isMonthAllowed实现),数组形式会检查“该月内是否存在任一被允许的日期”,函数形式则遍历该月每一天调用回调;随后传入VDatePickerMonthsallowedMonthsprop,在 VDatePickerMonths.tsx 中逐月计算isDisabled,禁用态月份按钮不可点击。

3.2 Colors:颜色定制

月份选择器的颜色通过colorheader-color两个 prop 控制:

  • color:选中月份(按钮)的主色;
  • header-color:头部标题区颜色;若未提供,头部自动使用color的值

对应源码逻辑在 VDatePicker.tsx:

const headerColor = toRef(() => props.headerColor ?? props.color)

官方示例(prop-colors.vue):

<v-date-picker v-model="picker" color="green-lighten-1" type="month" ></v-date-picker> <v-date-picker v-model="picker2" color="green-lighten-1" header-color="primary" type="month" ></v-date-picker>

第一个只设置了color,头部与选中态共用绿色;第二个额外设置header-color="primary",头部独立使用主题 primary 色。

3.3 Icons:图标覆盖

picker 默认使用的导航图标可以通过next-iconprev-iconyear-icon等 prop 覆盖为任意 Material Design Icons 名称(依赖项目已安装的 mdi 图标集)。官方示例(prop-icons.vue):

<v-date-picker v-model="picker" next-icon="mdi-skip-next" prev-icon="mdi-skip-previous" type="month" year-icon="mdi-calendar-blank" ></v-date-picker>

这些图标最终由 VDatePickerControls.tsx 渲染在顶部导航按钮上,分别对应“下一个月/上一个月/切换到年份视图”。

3.4 Multiple:多选月份

通过multipleprop 可以一次选择多个月份,此时v-model必须为数组。官方示例(prop-multiple.vue):

<v-date-picker v-model="months" type="month" multiple ></v-date-picker>
months: ['2018-09', '2018-10']

源码侧,VDatePickeruseProxiedModel转换逻辑(VDatePicker.tsx)在multiple为真时将模型包裹为数组,写入时若为单值则取v[0]。此外multiple也支持'range'字符串值或数字上限(见 VDatePickerMonth.tsx 的类型定义),当作为数字传入时表示最多可选的月份数量。

3.5 Readonly:只读模式

添加readonlyprop 即可禁止用户选择新日期,适合展示型场景。官方示例(prop-readonly.vue):

<v-date-picker v-model="date" type="month" readonly ></v-date-picker>

3.6 Show current:高亮“当前月份”

默认情况下,当前月份会以描边(outlined)按钮形式突出显示。show-currentprop 允许你:

  • 设为false:移除当前月份的高亮边框;
  • 传一个月份字符串(如'2013-07'):指定将哪个月份作为“当前”高亮显示。

官方示例(prop-show-current.vue):

<!-- 取消当前月高亮 --> <v-date-picker v-model="month1" :show-current="false" type="month" ></v-date-picker> <!-- 将 2013-07 作为“当前”月份高亮 --> <v-date-picker v-model="month2" show-current="2013-07" type="month" ></v-date-picker>

3.7 Width 与 Full-width:宽度控制

使用widthprop 指定固定宽度(支持数字或带单位的字符串,如"290"),使用full-width让 picker 撑满父容器宽度。官方示例(prop-width.vue):

<v-date-picker v-model="date" type="month" width="290" ></v-date-picker> <v-date-picker v-model="date" type="month" full-width ></v-date-picker>

四、进阶实战:Dialog 与 Menu 集成

在表单中,月份选择器最常见的用法是挂载到v-text-field上,通过v-menuv-dialog弹出。官方示例(misc-dialog-and-menu.vue)给出了完整实现,核心要点如下:

  1. v-text-field添加readonly:避免点击输入框时弹出移动端键盘;
  2. 使用no-title隐藏 picker 标题:节省垂直空间;
  3. 利用 picker 暴露的 slot 挂钩保存/取消逻辑v-menusave(date)会在确认时把暂存值写回模型;取消则维持旧值不变。

以 Menu 为例:

<v-menu ref="menu" v-model="menuActive" v-model:return-value="date" :close-on-content-click="false" max-width="290px" min-width="auto" transition="scale-transition" > <template v-slot:activator="{ props }"> <v-text-field v-model="date" label="Picker in menu" prepend-icon="mdi-calendar" readonly v-bind="props" ></v-text-field> </template> <v-date-picker v-model="date" type="month" no-title scrollable > <v-spacer></v-spacer> <v-btn color="primary" variant="text" @click="menu = false" > Cancel </v-btn> <v-btn color="primary" variant="text" @click="menu.save(date)" > OK </v-btn> </v-date-picker> </v-menu>

Dialog 的写法几乎相同,区别在于:

  • 使用v-dialog包裹,width="290px"persistent(点击遮罩不自动关闭);
  • 确定按钮调用dialog.save(date),取消按钮直接modal = false

这套模式能实现“确认前不改值、取消即还原”的交互,因为v-menu/v-dialogreturn-value绑定会在save()被调用时才提交到date

五、国际化(Internationalization)

月份选择器通过 JavaScript 原生Date对象支持国际化:使用localeprop 传入 BCP 47 语言标签,月份名称、头部文案、导航文案等都会随之本地化。官方示例(misc-internationalization.vue)演示了泰语(th)与瑞典语(sv-se):

<v-date-picker v-model="picker" locale="th" type="month" ></v-date-picker> <v-date-picker v-model="picker" locale="sv-se" type="month" ></v-date-picker>

从源码看,月份按钮的文本与无障碍标签由日期适配器(useDate())的format(date, 'monthShort')/format(date, 'month')生成(见 VDatePickerMonths.tsx),因此月份名完全跟随所设置的 locale。Vuetify 默认使用原生 Intl 能力(date适配器位于 packages/vuetify/src/composables/date),也支持通过date选项替换为 dayjs 等自定义适配器。

六、朝向切换(Orientation)

月份选择器支持两种朝向,默认portrait(竖版),设置landscape后切换为横版,头部信息区移动到左侧、内容区占据剩余宽度。官方示例(misc-orientation.vue)用一个v-checkbox动态切换:

<v-checkbox v-model="landscape" label="Landscape" ></v-checkbox> <v-date-picker v-model="picker" :landscape="landscape" type="month" ></v-date-picker>

横版下头部文案的行内换行处理可以在 VDatePicker.tsx 中看到:当格式化后的头部日期为三段式(含星期)时,VDatePicker会用换行符将其拆成两行显示,以适应横版较窄的头部区域。横版头部的宽度还可以通过landscapeHeaderWidthprop 进一步定制。

七、使用注意事项(Caveats)

::: warningv-date-picker接受ISO 8601的日期字符串(YYYY-MM-DD)。关于 ISO 8601 及其它日期标准的更多信息,请参阅国际标准化组织(ISO)发布的官方标准文档。 :::

落实到月份选择器场景,需要特别注意:

  • 模型格式:月份选择器的v-model使用YYYY-MM(如'2018-09''2013-07')这种“月份级”字符串,而底层日期适配器解析时仍遵循 ISO 8601 规范(如show-current="2013-07"会被解析为 2013 年 7 月);当与v-text-fieldv-menureturn-value组合时,请保持全链路格式一致。
  • 时区与截取:官方示例中常用new Date().toISOString().substr(0, 7)生成当前月份字符串,请注意toISOString()返回的是 UTC 时间,在非 UTC 时区边缘场景可能产生一天偏差;生产代码建议使用YYYY-MM显式构造。
  • readonly与键盘:将 picker 嵌入v-text-field时务必给输入框加readonly,否则移动端会弹出软键盘干扰操作(见本文第四节)。

八、相关组件与继续探索

月份选择器与以下 Vuetify 组件/文档配合使用效果最佳:

  • 日期选择器整体能力:date-pickers;
  • 弹出层容器:menus;
  • 时间选择器:time-pickers;
  • 月份网格源码:VDatePickerMonths.tsx;
  • 组合容器源码:VDatePicker.tsx;
  • 月份模式测试:VDatePicker.month.spec.ts(含快照 VDatePicker.month.spec.ts.snap),可用来验证月份选择、多选、范围选择等行为。

结语

本文围绕v-date-picker type="month"从基础用法、核心 props(allowed-dates、color/header-color、icons、multiple、readonly、show-current、width/full-width),到 Dialog/Menu 集成、国际化与朝向切换做了完整梳理,并结合 VDatePicker.tsx 与 VDatePickerMonths.tsx 等源码解释了这些能力背后的实现机制。掌握了这些内容,你就可以在报表筛选、账期管理、订阅周期等业务场景中,快速构建出体验完整的月份选择交互。

【免费下载链接】vuetify🐉 Vue Component Framework项目地址: https://gitcode.com/gh_mirrors/vu/vuetify

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 19:57:15

Python技术:把PDF练习题变成自动判题系统的完整方案

简介&#xff1a;这份题库答案解析面向 Python 初学者与备考者&#xff0c;以 30 道填空题形式梳理了常用语法知识点&#xff0c;涵盖数学函数、数据类型、列表与元组、字符串、变量类型、运算符、列表推导式、字典、切片操作、转义字符、print 函数、lambda 表达式及排序算法等…

作者头像 李华
网站建设 2026/9/19 19:55:34

LIGGGHTS与CFDEM耦合:DEM-CFD双向数据映射原理解析

简介&#xff1a;一份关于LIGGGHTS与CFDEM耦合的专题技术报告PDF&#xff0c;源自2013年DEM6国际会议&#xff0c;作者来自奥地利林茨大学颗粒流体建模系与DCS Computing公司。报告从工业颗粒过程建模痛点切入&#xff0c;指出颗粒物料的处理能耗与浪费问题&#xff0c;并系统梳…

作者头像 李华
网站建设 2026/9/19 19:51:07

OpenHarmony与React Native融合下的全屏加载遮罩优化实践

1. OpenHarmony与React Native技术融合背景在鸿蒙生态快速发展的当下&#xff0c;跨平台开发框架与OpenHarmony的融合成为开发者关注的重点。React Native作为Facebook推出的跨平台移动应用开发框架&#xff0c;通过react-native-oh/react-native-harmony适配层实现了对OpenHar…

作者头像 李华
网站建设 2026/9/19 19:50:59

Jackett怎么部署?Tracker聚合避坑一步到位

Jackett怎么部署&#xff1f;Tracker聚合避坑一步到位 【免费下载链接】Jackett API Support for your favorite torrent trackers 项目地址: https://gitcode.com/GitHub_Trending/ja/Jackett Jackett 是一个 BT 中转层&#xff0c;专门把各种 Tracker&#xff08;发种…

作者头像 李华