【问题标题】:Using new Date() with v-date-picker doesn't work使用带有 v-date-picker 的 new Date() 不起作用
【发布时间】:2018-07-03 19:21:43
【问题描述】:

我正在尝试使用 Vue 和 Vuetify 关注 this video,使用最初使用 new Date() 设置的数据值 date 将带有 v-model 的当前日期应用于日期选择器组件 v-date-picker

这是我项目的简化结构:

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 一起使用,但是如果您打开控制台,您会看到在尝试将 new Date()v-model 指令一起使用时,我在 v-date-picker 中遇到错误。日期选择器也没有呈现。 v-time-picker 但是工作正常。

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

[Vue 警告]:创建钩子时出错:“TypeError: dateString.split is not 一个函数”

发现于

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

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

【问题讨论】:

  • 显然 v-datepicker 期望绑定到一个字符串。你可能想试试data: { date: new Date().toJSON(), time: new Date().toJSON() }
  • 但是new Date()不是在输出字符串吗?
  • 不,它正在输出一个 Javascript Date 对象。
  • 啊,好吧。你的建议奏效了!谢谢!但是 v-date-pickerv-time-picker 期望不同的类型不是很奇怪吗?
  • 据我所见,两者都期待String

标签: vue.js vuetify.js


【解决方案1】:

显然(从您收到的错误消息中)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.

【讨论】:

【解决方案2】:

改为使用 value 属性来克服绑定。

例子

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>

【讨论】:

    【解决方案3】:

    就我而言,我需要将日期存储为 Date 对象而不是 String。因此,我没有在日期选择器中使用 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>

    【讨论】:

    • 非常感谢!完美的答案。确实:经典用例是通过 API 操作存储在数据库中的日期对象。像 'charliekassel/vuejs-datepicker' 这样的库会为你处理这一切。但是 Vuetify 日期选择器有点难。
    【解决方案4】:

    从官方的例子看,看来你得这样用

    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

    【讨论】:

      【解决方案5】:

      您可以将计算属性用作 v-model 的“垫片”。计算属性包含类型强制的所有逻辑,其他一切照旧。

      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>
      

      【讨论】:

        【解决方案6】:

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

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

        【讨论】:

          猜你喜欢
          • 2019-07-12
          • 2021-08-04
          • 2021-03-25
          • 1970-01-01
          • 2018-12-01
          • 2021-12-18
          • 2023-02-23
          • 2021-04-09
          • 2017-06-18
          相关资源
          最近更新 更多