【问题标题】:VueJS: How to bind a datetime?VueJS:如何绑定日期时间?
【发布时间】:2026-02-23 13:10:02
【问题描述】:

我从 WebAPI 收到一个具有此属性的 JSON 对象:

"BirthDate": "2018-02-14T15:24:17.8177428-03:00",

HTML:

<input type="date" v-model="BirthDate" />

我使用 VueJS 绑定该对象,但是 VueJS 在控制台中给出这个消息:

The specified value "2018-02-14T15:24:17.8177428-03:00" does not conform to the required format, "yyyy-MM-dd".

在这种情况下,唯一相关的部分是 2018-02-14,我可以丢弃其他信息。

我尝试创建一个双向过滤器以将该日期时间转换为所需的格式,但没有成功。见VueJS two way filter

如何将该日期/时间格式转换并绑定到 HTML 日期输入所需的日期格式?

【问题讨论】:

  • 使用输入类型文本并验证您的字段。

标签: vuejs2


【解决方案1】:

我认为这与 vueJs 无关,输入 type="date" 需要 YYYY-MM-DD 格式的日期,或者为空 看这里:https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/date,

如果将日期对象拆分为日期和时间字段会更好

【讨论】:

  • 是的,我需要一种方法将该日期转换为所需的格式,然后将其恢复,所以我很想在 VueJS 中使用双向过滤器。
  • 如何在客户端拆分日期,用户修改后恢复原格式?
  • @tony 应使用 getter 和 setter 作为日期代理的计算属性。至于格式化本身,有数百种方法可以在网上找到。
  • @oniondomes 说你应该使用计算属性,我稍后会尝试在 jsfiddle 上发布一个示例
  • @tony,您还应该记住,&lt;input type="date"&gt; 在您的原始数据中无法使用。
【解决方案2】:

考虑到myDate 是您的财产,您可以使用:

<input type="date" :value="myDate && myDate.toISOString().split('T')[0]"
                   @input="myDate = $event.target.valueAsDate">

由于v-modelis only syntactic sugar to :value and @input,您可以使用它们来代替。在这种情况下,我们使用并稍微更改了它们(格式化String,即日期输入到Date 对象的输出,反之亦然)。

查看演示和下面的注意事项。

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!',
    myDate: new Date('2011-04-11T10:20:30Z')
  },
  methods: {
    setMyDateToToday() {
    	this.myDate = new Date();
    },
    addADayToMyDate() {
      if (this.myDate) // as myDate can be null
        // you have to set the this.myDate again, so vue can detect it changed
        // this is not a caveat of this specific solution, but of any binding of dates
        this.myDate = new Date(this.myDate.setDate(this.myDate.getDate() + 1));
    },
  }
});
// Notes:
// We use `myDate && myDate.toISOString().split('T')[0]` instead
// of just `myDate.toISOString().split('T')[0]` because `myDate` can be null.

// the date to string conversion myDate.toISOString().split('T')[0] may
// have timezone caveats. See: https://*.com/a/29774197/1850609
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <p>{{ message }}</p>

  <input type="date" :value="myDate && myDate.toISOString().split('T')[0]"
                     @input="myDate = $event.target.valueAsDate">

  <p>
  <code>
  myDate: {{ myDate }}</code>
  </p>

  <button @click="setMyDateToToday">Set date one to today</button>
  <button @click="addADayToMyDate">Add a day to my date</button>
</div>

【讨论】:

【解决方案3】:

更正@acdcjunior,因为它不应该在一天之内关闭

new Vue({
  el: '#app',
  data: {
    message: 'Hello Vue.js!',
    myDate: new Date('2011-04-11T10:20:30Z')
  },
  methods: {
    setMyDateToToday() {
        this.myDate = new Date();
    },
    addADayToMyDate() {
      if (this.myDate) // as myDate can be null
        // you have to set the this.myDate again, so vue can detect it changed
        // this is not a caveat of this specific solution, but of any binding of dates
        this.myDate = new Date(this.myDate.setDate(this.myDate.getDate() + 1));
    },
    getDateClean(currDate) {
        // need to convert to UTC to get working input filter
        console.log(currDate);
        let month = currDate.getUTCMonth() + 1;
        if (month < 10) month = "0" + month;
        let day = currDate.getUTCDate();
        if (day < 10) day = "0" + day;
        const dateStr =
            currDate.getUTCFullYear() + "-" + month + "-" + day + "T00:00:00";
        console.log(dateStr);
        const d = new Date(dateStr);
        console.log(d);
        return d;
    }
  }
});
// Notes:
// We use `myDate && myDate.toISOString().split('T')[0]` instead
// of just `myDate.toISOString().split('T')[0]` because `myDate` can be null.

// the date to string conversion myDate.toISOString().split('T')[0] may
// have timezone caveats. See: https://*.com/a/29774197/1850609
<script src="https://unpkg.com/vue"></script>

<div id="app">
  <p>{{ message }}</p>

  <input type="date" :value="myDate && myDate.toISOString().split('T')[0]"
                     @input="myDate = getDateClean($event.target.valueAsDate)">

  <p>
  <code>
  myDate: {{ myDate }}</code>
  </p>

  <button @click="setMyDateToToday">Set date one to today</button>
  <button @click="addADayToMyDate">Add a day to my date</button>
</div>

【讨论】: