Appearance
DatePicker 日期选择器
用于在表单、筛选和业务配置中输入或选择日期,也可以选择月份、年份、季度、周和日期范围。只需要选择一天内具体时间时,请使用 TimePicker 时间选择器。
何时使用
- 用户需要填写生日、截止日期、排期日期、账期等日期字段。
- 用户需要在筛选表单中选择一个日期范围。
- 需要限制周末、历史日期或业务不可用日期时。
基础用法
vue
<template>
<x-date-picker v-model="date" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const date = ref('2026-06-04');
</script>受控值和事件
vue
<template>
<x-date-picker
v-model="date"
v-model:popup-visible="popupVisible"
allow-clear
@select="handleSelect"
@change="handleChange"
@clear="handleClear"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const date = ref('2026-06-04');
const popupVisible = ref(false);
const handleSelect = (value: string | undefined) => console.log('select', value);
const handleChange = (value: string | undefined) => console.log('change', value);
const handleClear = () => console.log('clear');
</script>月份、年份、季度和周
vue
<template>
<x-month-picker v-model="month" />
<x-year-picker v-model="year" />
<x-quarter-picker v-model="quarter" />
<x-week-picker v-model="week" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const month = ref('2026-06');
const year = ref('2026');
const quarter = ref('2026-Q2');
const week = ref('2026-23rd');
</script>日期范围
-
范围:2026-06-02 ~ 2026-07-29vue
<template>
<x-range-picker v-model="range" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const range = ref(['2026-06-01', '2026-06-30']);
</script>中国农历展示
-
农历辅助展示不会改变绑定值:2026-02-17,2026-06-19 ~ 2026-09-25vue
<template>
<x-date-picker v-model="date" show-lunar />
<x-range-picker
v-model="range"
:show-lunar="{ showSolarFestival: true }"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const date = ref('2026-02-17');
const range = ref(['2026-06-19', '2026-09-25']);
</script>带时间的日期选择
-
日期时间:2026-06-04 09:30:00日期时间范围:2026-06-02 00:00:00 ~ 2026-07-29 09:09:06vue
<template>
<x-date-picker v-model="dateTime" show-time />
<x-range-picker v-model="dateTimeRange" show-time />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const dateTime = ref('2026-06-04 09:30:00');
const dateTimeRange = ref(['2026-06-02 00:00:00', '2026-07-29 09:09:06']);
</script>月范围和受控面板
-
vue
<template>
<x-range-picker v-model="monthRange" mode="month" />
<x-date-picker
v-model="date"
v-model:picker-value="panel"
show-confirm-btn
/>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const monthRange = ref(['2026-01', '2026-06']);
const date = ref('2026-06-04');
const panel = ref('2026-06-01');
</script>动态范围限制
-
结束日期限制在开始日期前后 7 天内,等待操作vue
<template>
<x-range-picker
v-model="range"
:disabled-date="disabledDate"
@calendar-change="handleCalendarChange"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const range = ref<string[]>([]);
const draft = ref<string[]>([]);
const disabledDate = (current: Date, type?: 'start' | 'end') => {
if (type !== 'end' || !draft.value[0]) return false;
const start = new Date(draft.value[0]).getTime();
const target = current.getTime();
return Math.abs(target - start) > 7 * 24 * 60 * 60 * 1000;
};
const handleCalendarChange = (value: string[]) => {
draft.value = value.filter(Boolean);
};
</script>尺寸
vue
<template>
<x-date-picker v-model="date" size="mini" />
<x-date-picker v-model="date" size="small" />
<x-date-picker v-model="date" size="medium" />
<x-date-picker v-model="date" size="large" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const date = ref('2026-09-30');
</script>状态
vue
<template>
<x-date-picker v-model="date" allow-clear />
<x-date-picker default-value="2026-06-04" readonly />
<x-date-picker default-value="2026-06-04" disabled />
<x-date-picker v-model="date" error />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const date = ref('2026-09-30');
</script>禁用日期
vue
<template>
<x-date-picker v-model="date" :disabled-date="disabledDate" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const date = ref('2026-06-04');
const disabledDate = (current: Date) => {
const day = current.getDay();
return day === 0 || day === 6;
};
</script>禁止键盘输入
vue
<template>
<x-date-picker v-model="date" input-read-only />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const date = ref('2026-06-04');
</script>快捷项和值格式
vue
<template>
<x-date-picker
v-model="date"
value-format="timestamp"
:shortcuts="shortcuts"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const date = ref('');
const shortcuts = [
{ label: '今天', value: () => new Date() },
{ label: '本月初', value: '2026-06-01' },
];
</script>自定义内容
交付
vue
<template>
<x-date-picker v-model="date">
<template #prefix>交付</template>
<template #suffix-icon>📅</template>
<template #cell="{ label }">
<strong>{{ label }}</strong>
</template>
<template #extra>选择值:{{ date || '未选择' }}</template>
</x-date-picker>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const date = ref('2026-09-30');
</script>表单组合
点击校验查看结果
vue
<template>
<x-form ref="formRef" :model="formModel">
<x-form-item field="date" label="交付日期" required feedback>
<x-date-picker v-model="formModel.date" allow-clear />
</x-form-item>
<x-form-item field="range" label="周期">
<x-range-picker v-model="formModel.range" />
</x-form-item>
<x-form-item>
<x-space>
<x-button type="primary" @click="handleFormValidate">校验</x-button>
<x-button @click="handleFormReset">重置</x-button>
</x-space>
</x-form-item>
</x-form>
<p role="status">{{ formResult }}</p>
</template>
<script setup lang="ts">
import { reactive, ref } from 'vue';
import type { FormInstance, FieldRule } from 'x-next';
const formRef = ref<FormInstance>();
const formModel = reactive({ date: '', range: ['2026-06-01', '2026-06-30'] });
const formResult = ref('点击校验查看结果');
const handleFormValidate = async () => {
const errors = await formRef.value!.validate();
formResult.value = errors
? `校验失败:${Object.values(errors).map((error) => error.message).join(';')}`
: '校验通过';
};
const handleFormReset = () => {
formRef.value!.resetFields();
formResult.value = '已重置';
};
</script>键盘导航与焦点
-
聚焦输入后按 Down 进入日历;左右移动一天,上下移动一周,Enter 选择,Esc 返回输入。等待键盘选择vue
<template>
<x-date-picker v-model="date" aria-label="预约日期" :disabled-date="disabledDate" @change="onChange" />
<x-date-picker v-model="range" type="date-range" aria-label="预约日期范围" />
<p>{{ log }}</p>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const date = ref('2026-09-10');
const range = ref(['2026-09-10', '2026-09-15']);
const log = ref('等待选择');
const disabledDate = (date: Date) => [0, 6].includes(date.getDay());
const onChange = (value: string | undefined) => { log.value = `change: ${value || '空'}`; };
</script>日历只保留一个日期格的 Tab 停靠点。Home / End 到当前网格行首尾;PageUp / PageDown 翻页,日期模式加 Shift 翻年。月、年、季度模式按各自网格移动。方向键跳过禁用日期,不提交值;Enter 执行选择。范围模式可连续选择两端,Tab 正常切换两个输入框;Esc 或完成选择后焦点返回输入框,Tab 离开面板不会形成焦点陷阱。
原生 id、name、ARIA 和输入事件透传到真实输入;范围首端使用给定 ID,末端使用 ID-end。Form 自动关联标签、帮助及校验错误,独立使用时可设置 aria-label。
按需导入
ts
import {
DatePicker,
MonthPicker,
YearPicker,
QuarterPicker,
WeekPicker,
RangePicker,
} from 'x-next';样式按需引入(base.css 为共享基础层,多个组件只需引入一次):
ts
import 'x-next/style/base.css';
import 'x-next/style/date-picker.css';DatePicker Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
type | 选择器类型 | 'date' | 'month' | 'year' | 'quarter' | 'week' | 'date-range' | 'month-range' | 'year-range' | 'quarter-range' | 'week-range' | 'date' |
mode | RangePicker 范围类型 | 'date' | 'month' | 'year' | 'quarter' | 'week' | 'date' |
modelValue | 绑定值 | string | number | Date | Array<string | number | Date> | undefined |
defaultValue | 默认值 | string | number | Date | Array<string | number | Date> | undefined |
pickerValue | 面板显示日期 | string | number | Date | Array<string | number | Date> | undefined |
defaultPickerValue | 默认面板显示日期 | string | number | Date | Array<string | number | Date> | undefined |
placeholder | 占位文案 | string | string[] | 按类型生成 |
disabled | 是否禁用 | boolean | boolean[] | false |
readonly | 是否只读 | boolean | false |
disabledInput | 禁止输入框键盘输入但允许面板选择 | boolean | false |
inputReadOnly | 输入框只读,常用于移动端避免软键盘 | boolean | false |
error | 是否错误态 | boolean | false |
allowClear | 是否允许清除 | boolean | true |
format | 展示和解析格式 | string | 按类型生成 |
valueFormat | 值格式 | 'timestamp' | 'Date' | string | 与 format 一致 |
size | 输入框尺寸 | 'mini' | 'small' | 'medium' | 'large' | 继承 Form / medium |
dayStartOfWeek | 每周起始日 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 0 |
disabledDate | 禁用日期 | (current: Date, type?: 'start' | 'end') => boolean | undefined |
hideNotInViewDates | 隐藏非当前月份日期 | boolean | false |
popupVisible | 控制弹层显示 | boolean | undefined |
defaultPopupVisible | 默认弹层显示 | boolean | false |
position | 弹出位置 | 'top' | 'tl' | 'tr' | 'bottom' | 'bl' | 'br' | 'bl' |
popupContainer | 弹层挂载容器 | string | HTMLElement | undefined |
triggerProps | 透传 Trigger 配置 | Partial<TriggerProps> | undefined |
unmountOnClose | 关闭后销毁面板 | boolean | false |
shortcuts | 快捷项 | DatePickerShortcut[] | [] |
showToday | 是否显示今天 / 本月 / 今年按钮 | boolean | true |
showConfirmBtn | 是否显示确认按钮 | boolean | false |
showTime | 是否开启日期时间选择,仅 date / date-range 生效 | boolean | false |
timePickerProps | 时间列配置,支持 format、step、use12Hours、disabledHours、disabledMinutes、disabledSeconds、hideDisabledOptions、defaultValue | object | undefined |
disabledTime | 禁用时间,需要配合 showTime 使用 | (current?: Date, type?: 'start' | 'end') => object | undefined |
showLunar | 是否展示中国农历辅助信息,支持控制农历日期、农历节日、节气和公历节日 | boolean | { showLunarDate?: boolean; showLunarFestival?: boolean; showSolarTerm?: boolean; showSolarFestival?: boolean; fallbackText?: string } | false |
DatePicker Events
| 事件名 | 说明 | 参数 |
|---|---|---|
update:modelValue | 值更新 | value |
update:pickerValue | 面板值更新 | value |
change | 确认值变化 | value, date, dateString |
select | 面板选择但未必提交 | value, date, dateString |
calendar-change | 范围选择中间态变化 | value, date, dateString, info |
clear | 点击清除 | event |
ok | 点击确定 | value, date, dateString |
popup-visible-change | 弹层显示状态变化 | visible |
update:popupVisible | 受控弹层更新 | visible |
picker-value-change | 面板视图日期改变 | value, date, dateString |
select-shortcut | 点击快捷项 | shortcut |
focus | 输入框聚焦 | event |
blur | 输入框失焦 | event |
DatePicker Slots
| 插槽名 | 说明 |
|---|---|
prefix | 输入框前缀 |
suffix-icon | 输入框后缀图标 |
separator | 范围输入分隔符 |
cell | 自定义日期单元格 |
extra | 面板快捷区额外内容 |
DatePicker Methods
| 方法 | 说明 |
|---|---|
focus() | 聚焦输入框 |
blur() | 失焦输入框 |
交互说明
showTime仅在日期和日期范围模式生效,默认格式为YYYY-MM-DD HH:mm:ss,选择后需要点击“确定”提交。showLunar仅影响日期格辅助展示,不改变modelValue、format、范围排序或禁用逻辑;内置数据来自香港天文台 1901-2100 年公历 / 农历对照表,超出范围时默认不展示。- 非法手动输入不会提交新值;按 Enter 或失焦时会尝试按
format解析。 - 普通范围选择会在选择结束值后自动排序并提交;开启
showTime后需要点击“确定”提交。 valueFormat="timestamp"会让绑定值和事件值返回时间戳。