Vue 进阶(幺柒叁):表单元素日期校验
- 2021 年 11 月 10 日
本文字数:5993 字
阅读完需:约 20 分钟

一、前言
本文主要讲解基于element-ui datetimepicker实现日期时间,在表单校验中的校验逻辑及实现方法。
注:在表单检验时间组件时,应在检验中增加type: 'date',否则会提示检验对象错误问题。
二、Demo
vue 部分
<!--开始/结束日期,时间--><template> <el-row style="margin-top: 13px;"> <el-col :span="12"> <!--开始日期,时间--> <el-form-item label="开始日期,时间" prop="start"> <el-date-picker ref="start" v-model="eventFormModel.start" type="datetime" placeholder="请选择日期时间" align="right" :picker-options="pickerOptions1"> </el-date-picker> </el-form-item> </el-col> <el-col :span="12"> <!--结束日期,时间--> <el-form-item label="结束日期,时间" prop="end"> <el-date-picker ref="end" v-model="eventFormModel.end" type="datetime" placeholder="请选择日期时间" align="right" :picker-options="pickerOptions2"> </el-date-picker> </el-form-item> </el-col> </el-row></template>
js 部分
import Validator from '@/utils/validate.js'data() { return { // 开始时间 pickerOptions1: { shortcuts: [ { text: '今天', onClick (picker) { picker.$emit('pick', new Date()) } }, { text: '明天', onClick (picker) { const date = new Date() date.setTime(date.getTime() + 3600 * 1000 * 24) picker.$emit('pick', date) } }, { text: '后天', onClick (picker) { const date = new Date() date.setTime(date.getTime() + 3600 * 1000 * 24 * 2) picker.$emit('pick', date) } }, { text: '一周后', onClick (picker) { const date = new Date() date.setTime(date.getTime() + 3600 * 1000 * 24 * 7) picker.$emit('pick', date) } }] }, // 结束时间 pickerOptions2: { shortcuts: [ { text: '今天', onClick (picker) { picker.$emit('pick', new Date()) } }, { text: '明天', onClick (picker) { const date = new Date() date.setTime(date.getTime() + 3600 * 1000 * 24) picker.$emit('pick', date) } }, { text: '后天', onClick (picker) { const date = new Date() date.setTime(date.getTime() + 3600 * 1000 * 24 * 2) picker.$emit('pick', date) } }, { text: '一周后', onClick (picker) { const date = new Date() date.setTime(date.getTime() + 3600 * 1000 * 24 * 7) picker.$emit('pick', date) } }] }, start: [ { type: 'date', required: true, message: '请选择开始日期、时间', trigger: 'blur' }, {validator: Validator.validateStartDate(this, 'end', 'eventFormModel'), trigger: 'blur, change'} ], end: [ { type: 'date', required: true, message: '请选择结束日期、时间', trigger: 'blur' }, {validator: Validator.validateEndDate(this, 'start', 'eventFormModel', this.$t('flowMonitor.message.limitDate')), trigger: 'blur, change'} ] }}
校验逻辑 validate.js
/* * 日期前一个输入框校验 */ validateStartDate (currentPage, otherDateName, formName) { return (rule, value, callback) => { if (currentPage.$refs[otherDateName] !== undefined && currentPage.$refs[otherDateName].value !== '' && currentPage.$refs[otherDateName].value !== undefined) { if (value === '' || value === undefined) {// 有结束时间 currentPage.validateFlag = !currentPage.validateFlag if (!currentPage.validateFlag) { currentPage.$refs[formName].validateField(otherDateName) } callback() } else { currentPage.$refs[formName].validateField(otherDateName) callback() } } else { if (value !== '' && value !== undefined) { currentPage.$refs[formName].validateField(otherDateName) } else { currentPage.validateFlag = !currentPage.validateFlag if (!currentPage.validateFlag) { currentPage.$refs[formName].validateField(otherDateName) } }// 开始时间和结束时间都没有输入 callback() } } }, /* * 时间第二个输入框校验 */ validateEndDate (currentPage, otherDateName, formName, errorMsg) { return (rule, value, callback) => { if (currentPage.$refs[otherDateName] !== undefined && currentPage.$refs[otherDateName].value !== '' && currentPage.$refs[otherDateName].value !== undefined) { if (value === '' || value === undefined) {// 有结束时间 callback() } else { if (currentPage.$refs[otherDateName].value > value) { callback(new Error(errorMsg)) } callback() } } else { currentPage.validateFlag = !currentPage.validateFlag if (!currentPage.validateFlag) { currentPage.$refs[formName].validateField(otherDateName) } // 开始时间和结束时间都没有输入 callback() } } },
三、拓展阅读
四、延伸阅读
4.1 前言
在项目开发过程中,需要根据鼠标事件进行相应处理。现予以梳理。鼠标事件如下所示:
点击事件:
@click//单击@dblclick/ /双击@mousedown//按下@mouseup//抬起@contextmenu// 鼠标右键
悬浮事件及触发顺序:
@mouseover//划过@mouseenter//进入@mousemove//移动@mouseleave//离开@mouseout//移出
滚动事件:
@mousewheel
键盘事件
@keydown// 键盘按下时触发@keyup// 键盘弹起@keypress// 键盘按住时触发
获取按键的键码 e.keyCode
此外,方法后面跟keyCode值可以直接绑定键盘按键。
@keyup.13// 按回车键@keyup.enter// 回车@keyup.up// 上键@keyup.down// 下键@keyup.left// 左键@keyup.right// 右键@keyup.delete// 删除键@keyup.space// 空格
4.2 应用示例:实现文字溢出显示...鼠标移入浮层展示全部
实现逻辑:
将文字放到一个容器中,将容器的样式(主要是有关字体的样式)都设置为当前元素的样式,然后获取容器的宽,也就是文字的宽。
如果文字的宽度超过了当前元素的宽度,则给溢出隐藏的 css 样式
overflow :hidden;text-overflow: ellipsis;white-space: normal定义鼠标移入展示浮层,浮层中显示全部内容,鼠标移出销毁浮层。
通过自定义指令实现如上思路:
Vue.directive('showTips', { // el {element} 当前元素 componentUpdated (el) { const curStyle = window.getComputedStyle(el, '') // 获取当前元素的style const textSpan = document.createElement('span') // 创建一个容器来记录文字的width // 设置新容器的字体样式,确保与当前需要隐藏的样式相同 textSpan.style.fontSize = curStyle.fontSize textSpan.style.fontWeight = curStyle.fontWeight textSpan.style.fontFamily = curStyle.fontFamily // 将容器插入body,如果不插入,offsetWidth为0 document.body.appendChild(textSpan) // 设置新容器的文字 textSpan.innerHTML = el.innerText // 如果字体元素大于当前元素,则需要隐藏 if (textSpan.offsetWidth > el.offsetWidth) { // 给当前元素设置超出隐藏 el.style.overflow = 'hidden' el.style.textOverflow = 'ellipsis' el.style.whiteSpace = 'nowrap' // 鼠标移入 el.onmouseenter = function (e) { // 创建浮层元素并设置样式 const vcTooltipDom = document.createElement('div') vcTooltipDom.style.cssText = ` max-width:400px; max-height: 400px; overflow: auto; position:absolute; top:${e.clientY + 5}px; left:${e.clientX}px; background: rgba(0, 0 , 0, .6); color:#fff; border-radius:5px; padding:10px; display:inline-block; font-size:12px; z-index:19999 ` // 设置id方便寻找 vcTooltipDom.setAttribute('id', 'vc-tooltip') // 将浮层插入到body中 document.body.appendChild(vcTooltipDom) // 浮层中的文字 document.getElementById('vc-tooltip').innerHTML = el.innerText } // 鼠标移出 el.onmouseleave = function () { // 找到浮层元素并移出 const vcTooltipDom = document.getElementById('vc-tooltip') vcTooltipDom && document.body.removeChild(vcTooltipDom) } } // 记得移除刚刚创建的记录文字的容器 document.body.removeChild(textSpan) }, // 指令与元素解绑时 unbind () { // 找到浮层元素并移除 const vcTooltipDom = document.getElementById('vc-tooltip') vcTooltipDom && document.body.removeChild(vcTooltipDom) }})
使用时只需要溢出隐藏的元素上直接加上指令 v-show-tips 即可
<div v-show-tips class="title-text">{{ name }}</div>
4.3 应用示例:ul 鼠标移动到多个 li 标签上字体高亮
示例代码如下:
<ul v-for="(item,index) in tableData" :key="index" class="smart_nav_con"> <li :class="colorHover===index?'smart_index':'a_white'" style="display:inline-block; width: 100%" @mouseenter="spanHover(index)"> <a class="white a_color bnContentCss" @click.prevent="xiangxi(item)">{{ item.bnContent }}</a> <a class="white a_color bnDateCss" @click.prevent="xiangxi(item)">{{ item.bnDate }}</a> <a class="white a_color bnPublishNameCss" @click.prevent="xiangxi(item)">{{ item.bnPublishName }}</a> </li> </ul>
data(){ return{ colorHover: 0 }}methods:{ spanHover: function(index) { this.colorHover = index }}
.smart_nav_con{ color:black; position: relative; padding-left: 10px; padding-top: 12px; } .smart_nav_con .smart_index .a_white{ color:black; } .smart_nav_con .smart_index .a_color{ color:#00a0e9; } .smart_nav_con li a{ color:black; } .smart_nav_con .smart_index a{ color:#00a0e9; } .bnContentCss{ font-size: 14px; color: #666666; width: 60%; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; display: inline-block } .bnDateCss{ font-size: 14px; color: #9b9b9b; display: inline-block; float: right; margin-right: 13px; } .bnPublishNameCss{ font-size: 14px; color: #82796f; display:inline-block; float: right; position: relative; right: 15px; } .ulCss{ list-style: none; padding-left: 10px; padding-top: 8px; color:#fff; }
效果如下:
4.4 应用示例:移动到元素上对应改变背景色
<ul v-for="(item,index) in tableData" :key="index" style="list-style: none;padding-left: 10px;"> <li :class="active === index?'smart_index':'a_white'" style="display:inline-block; width: 98%" @mouseover="mouseOver(index)" @mouseleave="mouseLeave(index)"> <a class="circle"> <div class="circletext" @click.prevent="xiangxi(item)" v-html="formatDate(item.bnDate)" /> </a> <div style="display:inline-block;position: relative;top: 3px;width: 80%;margin-left: 12px"> <a style="width: 80%" @click.prevent="xiangxi(item)"> <span class="NoticeTitle">{{ item.bnTitle }}</span> </a> <a style="width: 80%" @click.prevent="xiangxi(item)"> <span class="NoticeContent">{{ item.bnContent }}</span> </a> </div> </li></ul>
data(){ return{ active: 0, }}methods:{ mouseOver: function(index) { this.active = index }, mouseLeave: function(index) { this.active = index }}
.smart_index{ background-color: #F5F5F5;} .a_white{ background-color: #ffffff; }
效果如下:
4.5 拓展阅读
版权声明: 本文为 InfoQ 作者【No Silver Bullet】的原创文章。
原文链接:【http://xie.infoq.cn/article/6778ae4334cc493643da2b246】。文章转载请联系作者。
No Silver Bullet 2021.07.09 加入
岂曰无衣 与子同袍











评论