在Vue中datePicker的使用是比较多的,但是用到a-date-picker的时候难免会遇到一下预料之外的事情。
在设置默认值这个事情上,就给了当头一棒,设置老不成功。
踩坑
先说如何踩坑,在一般思维观念上,a-date-picker绑定一个model,然后model在初始赋值,值直接用字符串赋值,这就遇上事了。
报错:Warning: [antdv: DatePicker] value provides invalidate moment time. If you want to set empty value, use null instead.
原因
a-date-picker其实数据模型是moment,使用a-date-picker就必须结合moment来实现。
所以model用字符串赋值就直接挂掉了。
解决方法
ant design vue中 时间选择器和日期选择器,需要使用到moment,由于在使用日期选择器的时候,我们在获取一个时间之后,获取到的不是时间戳,也不是字符串,在控制台打印之后,会获取到一个Monent对象,要想将这个获取到的moment对象转换成我们自己想要的格式(如YYYY/MM/DD),就要使用moment.js这个第三方包。更加详细的用法可以查看官方文档:moment.js官方文档
首先的得安装moment的插件
npm install moment -save
复制
安装完成之后,在main.js中做全局引入并挂载带当前vue实例对象中,挂载之后就可以在当前项目任意位置使用该方法,由于我用的是nuxt,所以找到antd-ui.js这个文件
import moment from 'moment' import 'moment/locale/zh-cn' moment.locale('zh-cn') //设置语言 或 moment.lang('zh-cn'); Vue.prototype.$moment = moment //挂载到当前vue实例对象
复制
这样就可以在项目中使用moment.js对日期进行格式化了。
<template> <div> <a-date-picker v-model="myDate"/><br/> <a-button @click="btnClick">选择日期之后点击输出当前选中时间</a-button> </div> </template> <script> export default { data(){ return{ //由于日期控件上绑定的是一个moment对象,所以初始化值要绑定一个undefined/而不是一个空字符串 myDate:undefined, } }, methods:{ btnClick(){ //输出当前选中时间 console.log(this.myDate,'-----'); // 将当前选中时间进行格式化 var currentPicker = this.$moment(this.myDate).format('YYYY-MM-DD') console.log(currentPicker) // 查看格式化之后的类型 console.log(typeof currentPicker) } } } </script>
复制
在这个控件身上 有一个change事件,在这个回调中可以拿到当前选中的值,该值也是一个moment对象。
事件绑定:
<a-date-picker v-model=“myDate” @change=“datePickerChange”/>
在methods中定义该回调:
datePickerChange(value){
console.log(value,’-----------------’)
}
如果用官网上说的那种change,其实是可以取到字符串的,但是回显的时候会报错,如果不需要回显,用这种change取到里面的第二个值timeString,是可行的。
<template> <div> <a-date-picker @change="onChange"/><br/> <a-button @click="btnClick">选择日期之后点击输出当前选中时间</a-button> </div> </template> <script> export default { data(){ return{ //由于日期控件上绑定的是一个moment对象,所以初始化值要绑定一个undefined/而不是一个空字符串 myDate:undefined, } }, methods:{ btnClick(){ //输出当前选中时间 console.log(this.myDate,'-----'); // 将当前选中时间进行格式化 var currentPicker = this.$moment(this.myDate).format('YYYY-MM-DD') console.log(currentPicker) // 查看格式化之后的类型 console.log(typeof currentPicker) }, onChange(time, timeString) { this.myDate = timeString } } } </script>
复制
因为我们是需要回显的,这里详细讲一下从后台传值回来显示在a-date-picker控件中是如何实现的。
如果不用moment来处理后端返回的字符串类型日期格式,就会报错Warning: [antdv: DatePicker] value provides invalidate moment time. If you want to set empty value, use null instead.
分两种情况,一种是后台返回字符串,还有就是后台返回时间戳,大家可根据自己的实际情况运用。
1.从后台获取到的值是string类型的值
刚刚已经说过,日期控件绑定的是一个moment对象,那么我们要将这个后台返回的string转换成moment对象。
首先就是页面中的控件,还说多插一嘴,data模型数据的值初始为undefined:
<a-date-picker v-model="myDateTwo"/><br/>
复制
后台取值并转换:
created(){ // 模拟从后台传回来的值 var myDateStr = '2021/07/12'; // 将后台返回的字符串进行转换,并赋值 this.myDateTwo = this.$moment(myDateStr, 'YYYY-MM-DD') }
复制
页面加载完毕之后时间控件就会显示后台传回来的初始值。
2.从后台获取到的值是时间戳
这里需要特别注意的是,从后台获取时间戳之后,不能直接使用momentjs将时间戳转换为Moment对象,否则会报如下警告,并且页面上的时间不能正常显示,也不能直接将时间戳赋值给时间控件绑定的变量:
created(){ // 模拟从后台传回来的值,其实是当前时间戳 var myDateNumber = Date.now() console.log(myDateNumber,'------');//1592118355677 console.log(typeof myDateNumber);//当前时间戳类型number // 如果后台传回来的时间戳是string类型,要使用Number()方法转换为number类型 // 下面只是将时间戳转换成了字符串格式的时间(多出一步) var myDateStr = this.$moment(Number(myDateNumber)).format('YYYY-MM-DD')//2021-07-12 // 将字符串格式的再转换为Moment对象 this.myDateTwo = this.$moment(myDateStr, 'YYYY-MM-DD') }
复制
需要注意的是,不能直接使用时间戳转换为Moment对象,我是先将时间戳转换为字符串格式的值,再将值转换成Moment对象,感觉有点繁琐,如果大家有什么更好的方法可以交流一下。