Vue3公历与回历双向转换:如何将手动输入改为日期选择器?
问题
现有代码实现了手动输入回历/公历日期时互相转换的功能,现在需要将手动输入的文本框替换为日期选择器,该如何修改?
现有代码如下:
<template> <div style="margin: 100px"> <label for="hijri-date">التاريخ بالهجري:</label> <input id="hijri-date" v-model="hijriDate" @input="convertToGregorian" type="text" placeholder="YYYY-MM-DD" /> <br /> <label for="gregorian-date">التاريخ بالميلادي:</label> <input id="gregorian-date" v-model="gregorianDate" @input="convertToHijri" type="text" placeholder="YYYY-MM-DD" /> </div> </template> <script> import moment from "moment"; import momentHijri from "moment-hijri"; export default { data() { return { hijriDate: "", gregorianDate: "", }; }, methods: { convertToGregorian() { const hijriMoment = momentHijri(this.hijriDate, "iYYYY/iM/iD"); const gregorianDate = hijriMoment.toDate(); this.gregorianDate = moment(gregorianDate).format("YYYY-MM-DD"); }, convertToHijri() { const gregorianMoment = moment(this.gregorianDate, "YYYY-MM-DD"); const hijriDate = momentHijri(gregorianMoment.toDate()).format( "iYYYY/iM/iD" ); this.hijriDate = hijriDate; }, }, }; </script>
解决方案
方案一:原生HTML5公历日期选择器
原生type="date"输入框自带公历日期选择器,无需额外依赖,仅需修改输入框类型:
<template> <div style="margin: 100px"> <label for="hijri-date">التاريخ بالهجري:</label> <!-- 原生不支持回历选择器,此处保留文本框或改用第三方组件 --> <input id="hijri-date" v-model="hijriDate" @input="convertToGregorian" type="text" placeholder="YYYY-MM-DD" /> <br /> <label for="gregorian-date">التاريخ بالميلادي:</label> <input id="gregorian-date" v-model="gregorianDate" @input="convertToHijri" type="date" /> </div> </template> <script> // 原有逻辑不变 import moment from "moment"; import momentHijri from "moment-hijri"; export default { data() { return { hijriDate: "", gregorianDate: "", }; }, methods: { convertToGregorian() { const hijriMoment = momentHijri(this.hijriDate, "iYYYY/iM/iD"); const gregorianDate = hijriMoment.toDate(); this.gregorianDate = moment(gregorianDate).format("YYYY-MM-DD"); }, convertToHijri() { const gregorianMoment = moment(this.gregorianDate, "YYYY-MM-DD"); const hijriDate = momentHijri(gregorianMoment.toDate()).format( "iYYYY/iM/iD" ); this.hijriDate = hijriDate; }, }, }; </script>
说明:原生输入框仅支持公历日历,回历选择器需要依赖第三方UI组件实现。
方案二:第三方UI组件实现双日历选择(推荐)
以Element Plus(Vue3)为例,结合moment-hijri实现回历和公历的可视化日期选择器:
1. 安装依赖
npm install element-plus moment moment-hijri --save
2. 完整组件代码
<template> <div style="margin: 100px; width: 320px"> <!-- 回历日期选择器 --> <el-form-item label="التاريخ بالهجري:"> <el-date-picker v-model="hijriDate" type="date" :format="hijriDisplayFormat" :value-format="hijriValueFormat" placeholder="选择回历日期" @change="handleHijriChange" /> </el-form-item> <!-- 公历日期选择器 --> <el-form-item label="التاريخ بالميلادي:"> <el-date-picker v-model="gregorianDate" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD" placeholder="选择公历日期" @change="handleGregorianChange" /> </el-form-item> </div> </template> <script setup> import { ref } from "vue"; import moment from "moment"; import momentHijri from "moment-hijri"; import { ElDatePicker, ElFormItem } from "element-plus"; // 回历格式配置 const hijriDisplayFormat = "iYYYY-iM-iD"; const hijriValueFormat = "iYYYY-iM-iD"; // 绑定的日期值 const hijriDate = ref(""); const gregorianDate = ref(""); // 回历转公历 const handleHijriChange = (val) => { if (!val) return; const hijriMoment = momentHijri(val, hijriValueFormat); gregorianDate.value = moment(hijriMoment.toDate()).format("YYYY-MM-DD"); }; // 公历转回历 const handleGregorianChange = (val) => { if (!val) return; const gregorianMoment = moment(val); hijriDate.value = momentHijri(gregorianMoment.toDate()).format(hijriValueFormat); }; </script> <style> /* 引入Element Plus样式 */ @import "element-plus/dist/index.css"; </style>
Vue2 + Element UI 适配版本
<template> <div style="margin: 100px; width: 320px"> <el-form-item label="التاريخ بالهجري:"> <el-date-picker v-model="hijriDate" type="date" :format="hijriDisplayFormat" :value-format="hijriValueFormat" placeholder="选择回历日期" @change="handleHijriChange" /> </el-form-item> <el-form-item label="التاريخ بالميلادي:"> <el-date-picker v-model="gregorianDate" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD" placeholder="选择公历日期" @change="handleGregorianChange" /> </el-form-item> </div> </template> <script> import moment from "moment"; import momentHijri from "moment-hijri"; import { DatePicker, FormItem } from "element-ui"; export default { components: { ElDatePicker: DatePicker, ElFormItem: FormItem }, data() { return { hijriDate: "", gregorianDate: "", hijriDisplayFormat: "iYYYY-iM-iD", hijriValueFormat: "iYYYY-iM-iD" }; }, methods: { handleHijriChange(val) { if (!val) return; const hijriMoment = momentHijri(val, this.hijriValueFormat); this.gregorianDate = moment(hijriMoment.toDate()).format("YYYY-MM-DD"); }, handleGregorianChange(val) { if (!val) return; const gregorianMoment = moment(val); this.hijriDate = momentHijri(gregorianMoment.toDate()).format(this.hijriValueFormat); } } }; </script> <style> @import "~element-ui/lib/theme-chalk/index.css"; </style>
关键要点:
- 用
@change替代原@input事件,仅在用户确认选择日期后触发转换,避免无效操作。 - 通过
format控制日期选择器面板的显示格式,value-format控制绑定值的格式,回历使用moment-hijri专属的iYYYY/iM/iD标识符。 - 添加空值判断,防止清空选择时出现转换错误。
内容的提问来源于stack exchange,提问作者user22317151
相关产品推荐
相关产品推荐

