关于el-time-picker使用错误的记录

7 篇文章 0 订阅
3 篇文章 0 订阅

之前在紧急参与一个PC管理后台的项目,项目的基础架子是花裤衩大佬的vue-element-admin()vue2版本),。其中有一个需求是列表数据中数据回显时候,有关时间部分的数据在回显/编辑的情况下,提交时获取的值有问题。虽然后面解决了,但还是觉得简单粗暴,所以记录下看大佬们有没有更好的方案。

同时也因为自己以为工作关系在学习React,所以选择了ant design vue来跟element-ui做对比,(ant design 有vue和react版本,本次对比选择react版本)

element-ui

数据回显为两个时间,开始时间和结束时间。由于是两个时间在一行,最开始使用的是时间范围选择(is-range),后来发现有问题,先改成分离版本的,交付初版代码。

el-time-picker range版本

最开始使用就是添加is-range属性的版本。参照官方示例
在这里插入图片描述

<el-time-picker
  is-range
  v-model="dataTime"
  range-separator=""
  start-placeholder="开始时间"
  end-placeholder="结束时间"
  placeholder="选择时间范围"
>
</el-time-picker>
// 日期回显处理
this.dataTime = [new Date('2023/01/01 ' + row.beginTime), new Date('2023/01/01 ' + row.endTime)]
// 获取dataTime的值
[
  Sun Jan 01 2023 05:00:00 GMT+0800 (中国标准时间), 
  Sun Jan 01 2023 08:00:00 GMT+0800 (中国标准时间)
]

  • 经过日期转换之后,回显正常,但获取到的值是标准日期格式
<el-time-picker
  is-range
  v-model="dataTime"
  range-separator=""
  :picker-options="pickerOption"
  value-format="HH:mm:ss"
  start-placeholder="开始时间"
  end-placeholder="结束时间"
  placeholder="选择时间范围"
>
</el-time-picker>
  • 添加format格式化之后,回显后不修改获取的值仍是标准日期格式;修改任一个时间就是时分秒的格式。

以上的倒还好说,自己做下转化处理应该也能解决。但是在新增时候有一点是最不符合需求的:开始-结束的时间有多个,有的时必填项,有的时非必填项。

而is-range版本不符合需求的原因就是必须要默认值。。。(新增情况下怎么可能会给非必填项赋默认值,抓狂!!!)

所以在之后就改成时间分离的版本,使用两个时间选择器。

el-time-picker分离版

参照官方例子,默认值要讲述进行日期转化处理。(写文章时才发现问题,后续再讲,是真的坑。。。)
在这里插入图片描述

初始版本
  • 新增数据
<el-time-picker v-model="beginTime" />
<span></span>
<el-time-picker v-model="endTime"/>

// 不选择时间  
// { beginTime:undefined,endTime:undefined }
// 选择时间    
// { beginTime:Sun Jan 01 2023 17:11:20 GMT+0800 (中国标准时间),
//   endTime:Sun Jan 01 2023 17:12:22 GMT+0800 (中国标准时间)
// }

这样的话,不选时间时得到的值是undefined,选择时间后的值是标准时间格式,

  • 编辑数据
// 数据处理
this.beginTime = new Date('2023/01/01 ' + row.beginTime)
this.endTime = new Date('2023/01/01 ' + row.endTime)
// 不修改/修改时间    
// { beginTime:Sun Jan 01 2023 17:11:20 GMT+0800 (中国标准时间),
//   endTime:Sun Jan 01 2023 17:12:22 GMT+0800 (中国标准时间)
// }

而需求上要求的是时-分-秒格式。所以针对显示问题,加了format和value-format。

format版本
  • format是在pickerOption中,是页面中选中时间的显示格式
  • value-format是获取值的显示格式
<el-time-picker
  v-model="beginTime"
  :picker-options="pickerOption"
  value-format="HH:mm:ss"
/>
<span></span>
<el-time-picker 
  v-model="endTime"
  :picker-options="pickerOption"
  value-format="HH:mm:ss"/>
// js部分
pickerOption: {
  format: 'HH:mm:ss'
}

二者的区别在于格式显示的选择不同,

TimePicker中format的选择格式为:小时:HH,分:mm,秒:ss,AM/PM A而value-format的选择格式则为日期格式,时分秒的部分是相同的,也有另外一部分,(12小时制和24小时制)主要区别在于:大写是24小时,小写为12小时;单字母为不补0格式,双字母补0;大写A代表AM/PM,小写a代表am/pm 。

加完之后,不选择时候为空字符串,选完为HH:mm:ss格式。但还有问题。

问题在于: 详情数据回显时候,是以new Date() 格式填充,如果不做修改,获取的值就会是标准时间格式,而不是value-format规定的格式,所以就是个坑,具体情况如下:

// 回显后不做修改(Date格式)
beginTime Sun Jan 01 2023 17:11:20 GMT+0800 (中国标准时间),
endTime   Sun Jan 01 2023 17:15:20 GMT+0800 (中国标准时间),

// 回显后修改(String格式)
firstBeginTime 17:11:20
firstEndTime   17:15:20

所以,我这里就做了一下处理:如果获取得值不为字符串,则进行日期格式的处理。还单独封装了个函数,经过函数处理后,再转化为时分秒格式。

transTimeFormat (time) {
  if (typeof time === 'string') {
    const date = parseTime(new Date(), '{y}/{m}/{d}')
    time = date + ' ' + time
  }
  return time
},

这里算是勉强可以使用,功能正常,新增和编辑情况下获取的值都是时分秒格式的字符串。这也是我交上去的代码初版。

最新版

但是,在我写这篇文章的时候才发现一个细节:分离版的时间选择器绑定的值可以是字符串!!!
在这里插入图片描述
这个细节也是我无意间测试出来的。

在分离版的第一份代码里,还没有处理回显时的日期转化时,值的结果情况与之前一样。

<el-time-picker v-model="beginTime" />
<span></span>
<el-time-picker v-model="endTime"/>

比较偶然的是,加了format之后,我依旧没有处理回显时的日期转化,但此刻的情况变了

<el-time-picker
  v-model="beginTime"
  :picker-options="pickerOption"
  value-format="HH:mm:ss"
  style="width:180px"
/>
<span></span>
<el-time-picker
  v-model="endTime"
  :picker-options="pickerOption"
  value-format="HH:mm:ss"
  style="width:180px"
/>
  • 新增情况:未选择时为空字符串,选择后为时分秒格式
  • 回显情况:回显正常,修改与否都为时分秒格式

天!!!这就是我希望的情况,是什么原因呢?所以我就发现了v-model绑定的格式问题

怪我,怪我学艺不精,囫囵吞枣。。。

antd design react

这一份的内容,主要作用是进行下对比。在学习React相关东西,就拉过来做个比较,我觉得这种问题肯定每个框架都会遇到,但各自的处理应该会不一样。

代码比较简略,莫介意哈

TimePicker

react中引入了moment插件,在给时间选择器回显的时候,先经过moment处理,不然会报错。

这样就导致了就是未修改的情况和修改的情况下获取到的值都是moment对象,在提交时候需要进行一次moment处理。(诶!这好像和我处理的方式有点像啊😎,略同,略同,哈哈哈)

Form.setFieldsValue({
  time: moment(time, 'HH:mm:ss')
})
<Form
  form={addOrEditForm}
  labelCol={{ span: 4 }}
  wrapperCol={{ span: 16 }}
>
  <Form.Item
    label="时间"
    name="time"
    rules={[{ required: true, message: '请选择时间' }]}
  >
    <TimePicker size="large" format='HH:mm' />
  </Form.Item>
</Form>

Form
.validateFields()
.then((values) => {
  let time = moment(values.time).format('HH:mm:ss')
  console.log(time);
})

其他的就不在多对比了,主要内容还是最新版的正确。话说有没有和我一样遭遇的同学,欢迎评论区畅谈心路历程(本人OS: 坑,大坑,一大坑,是一大坑,就是一大坑)

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端SkyRain

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值