Devextreme-vue + Vue2日历下拉框的使用
npm install devextreme@22.2.6 devextreme-vue@22.2.6
效果图:
<template><div style="padding: 20px"><!-- 日期选择框 --><DxDateBoxv-model="selectedDate"displayFormat="yyyy/M/d"placeholder="请选择大于最近版本且不早于今天的有效日期":min="minSelectableDate":show-clear-button="true":use-calendar="true":width="200":disabled="loading" @value-changed="handleDateChange"/><!-- 提交按钮 --><DxButtontext="提交"type="default"styling-mode="contained"style="margin-left: 10px":width="100":disabled="!selectedDateStr || loading"@click="submit"/></div>
</template><script>
import { DxDateBox } from 'devextreme-vue/date-box';
import { DxButton } from 'devextreme-vue/button';
import 'devextreme/dist/css/dx.light.css';
import moment from 'moment';// 中文支持
import { locale, loadMessages } from 'devextreme/localization';
import dxMessagesZh from 'devextreme/localization/messages/zh';
loadMessages(dxMessagesZh);
locale('zh-CN');export default {components: { DxDateBox, DxButton },data() {return {list: [], // 初始为空,等待后端加载selectedDate: null,selectedDateStr: '',loading: true // 控制加载状态};},created() {// 模拟异步从后端加载数据setTimeout(() => {this.list = [{ id: 1, date: '2025-08-09', isValid: true },{ id: 2, date: '2025-08-10', isValid: true },{ id: 3, date: '2025-08-05', isValid: false },{ id: 4, date: '2025-08-08', isValid: true },{ id: 5, date: '2025-08-15', isValid: true }];this.loading = false; // 关闭加载状态}, 800); // 模拟网络延迟},computed: {/*** 功能:计算最小可选日期* * 原理:初始化改变了依赖的list 又因为list是响应数据vue监听到会触发minSelectableDate方法 * * 业务:用户可选的日期必须同时满足两个条件* 1.大于 list 中所有 isValid: true 记录的 最大日期* 2.大于等于今天(当前系统日期)*/minSelectableDate() {const latestValidDate = this.findLatestValidDate(this.list, 'date');// 当前日期(今天)00:00:00const today = moment().startOf('day');// 历史版本最大有效日期加上 1 天(得到“最大有效日期的下一天”)const nextDayAfterLatest = latestValidDate ? latestValidDate.clone().add(1, 'day').startOf('day') : null;// 最小可选日期 == 两者中较大的(即更晚的日期)const minDate = nextDayAfterLatest ? moment.max(nextDayAfterLatest, today) : today;return minDate.toDate();}},methods: {// 找出 list 中 isValid === true 的记录,并返回指定字段(生效日期)的最大日期findLatestValidDate(list, fieldName) {let max = null;for (const item of list) {if (!item.isValid) continue;const date = moment(item[fieldName], 'YYYY-MM-DD');if (!date.isValid()) continue;if (max === null || date.isAfter(max, 'day')) {max = date;}}return max;},/*** 功能:更新要提交的表单数据* * e 是 DevExtreme 的事件对象,用户选择下来日期自动带过来* 结构: e = {* value: Date | null, // 用户选中的日期(JavaScript Date 对象),或 null(清空时)* previousValue: ... // 上一次的值(这里没用到)* }*/handleDateChange(e) {this.selectedDateStr = e.value ? moment(e.value).format('YYYY/M/D') : '';},/*** 功能:模拟保存并提交表单*/submit() {if (!this.selectedDateStr) return;alert(`已提交:${this.selectedDateStr}(模拟成功)`);}}
};
</script><style scoped>
.dx-datebox {margin-right: 10px;
}
</style>