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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 13:17:05