将 new Date() 与 v-date-picker 一起使用不起作用

Using new Date() with v-date-picker doesn't work

我正在尝试按照 this video 使用 Vue 和 Vuetify 将当前日期 v-model 应用到日期选择器组件 v-date-picker 使用数据值 date最初是用 new Date().

设置的

这是我项目的简化结构:

JS

new Vue({
  el:"#app",
  data: {
    date: new Date(),
    time: new Date()
  }
})

模板

<div id="app">
  <v-date-picker v-model="date"></v-date-picker>
    {{ date }}
  <v-time-picker v-model="time"></v-time-picker>
</div>

这里是 CodePen。不幸的是,我无法让 Vuetify CSS 与 CodePen 一起工作,但是如果你打开控制台,你会看到我在尝试使用 [=15= 时在 v-date-picker 中遇到错误] 与 v-model 指令。日期选择器也没有呈现。 v-time-picker 然而工作正常。

在我的本地设置中,我使用 vue-cli 创建了一个 Vue 项目。这是我遇到的错误:

[Vue warn]: Error in created hook: "TypeError: dateString.split is not a function"

found in

---> at src/components/Meetup/CreateMeetup.vue at src/App.vue

我正在按照我正在学习的教程进行操作,所以我不知道这是否是最新版本的 Vue 或 Vuetify 的错误?还是我遗漏了什么?

显然(根据您收到的错误消息)v-datepicker 期望绑定到 String。你可能想试试

data: { 
    date: new Date().toJSON(), 
    time: new Date().toJSON() 
}

https://codepen.io/connexo/pen/ypWxLv

另请参阅 Vuetify API 文档(明确指出它希望 v-model 属于 String 类型):

v-model   String    null    Controls the displayed date. Must use ISO 8601 format.

从官方的例子来看,好像要这么用

data: { 
    date: new Date().toISOString().substr(0, 10), 
    time: new Date().getHours() + ':' + new Date().getMinutes(), 
}

例子-

https://github.com/vuetifyjs/vuetifyjs.com/blob/master/src/examples/date-pickers/dateDialogAndMenu.vue

相反,使用值属性来克服绑定。

示例

data: { 
    date: new Date().toISOString().substr(0, 10)
}
<v-text-field slot="activator" :value="dataValue.datePass" label="Date" append-icon="event" readonly style="font-size:14px"></v-text-field>
<v-date-picker v-model="dataValue.datePass"></v-date-picker>

在我的例子中,我需要将日期存储为日期对象而不是字符串。因此,我没有在日期选择器中使用 v-model,而是使用 @input 和 :value.

来处理这个问题

new Vue({
  el: '#app',
  data() {
    return {
      isActive: false,
      theDate: new Date()
    }
  },
  computed: {
    formattedDate() {
      return this.theDate ? moment(this.theDate).format('MM/DD/YYYY') : undefined; // Custom format
    },
    datePickerFormattedDate() {
      return this.theDate ? moment(this.theDate).format('YYYY-MM-DD') : undefined; // Date picker objects needs date in this particular format
    }
  },
  methods: {
    inputHandler(date) {
      if (typeof date === 'string')
        date = moment(date).toDate();
      this.isActive = false;
      this.theDate = date;
    }
  }
})
<html>
  <head>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/locale/en-gb.js">
    </script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vuetify/1.3.12/vuetify.min.js">
    </script>
    <script src="https://cdn.jsdelivr.net/momentjs/2.10.6/moment-with-locales.min.js">
    </script>


    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/material-design-icons/3.0.1/iconfont/material-icons.min.css">
    
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900|Material+Icons">
    
    <link rel="stylesheet" href="https://unpkg.com/vuetify/dist/vuetify.min.css">
    <meta name="viewport" content="width=device-width, initial-scale=1">
  </head>
  <body>
    <div id="app">
      <v-app id="inspire">
        <v-content>
          <v-container>
            <v-layout row wrap>
              <v-flex pb-4 xs12>
                Stored date: {{ theDate }}
              </v-flex>
              <v-flex xs12>
                <v-text-field :readonly="true" :value="formattedDate" label="I want to enter dates here"></v-text-field>
                <v-menu :close-on-content-click="true" v-model="isActive" :nudge-right="40" lazy transition="scale-transition" offset-y full-width min-width="290px">
                  <v-icon slot="activator">event</v-icon>

                  <v-date-picker :value="datePickerFormattedDate" @input="inputHandler"></v-date-picker>
                </v-menu>
              </v-flex>
            </v-layout>
          </v-container>
        </v-content>
        <v-footer></v-footer>
      </v-app>
    </div>

  </body>
</html>

您可以使用计算的 属性 作为 v 模型的 "shim"。计算的 属性 包含类型强制的所有逻辑,其他一切照常。

JS

new Vue({
  el:"#app",
  data: {
    date: new Date()
  },
  computed: {
    // "shim" for v-date-picker
    sdate: {
      get() {
        return this.date?.toISOString()
      },
      set(val) {
        this.date = new Date(val)
      }
    }
  }
})

模板

<div id="app">
  <v-date-picker v-model="sdate"></v-date-picker>
  {{ date }}
</div>

Vuetify 日期选择器需要特定格式的日期 ('YYYY-MM-DD')。这可以通过将其替换为:-

来解决
new Vue({
  el:"#app",
  data: {
    date: moment(new Date()).format('YYYY-MM-DD'),
    time: new Date()
  }
})