先上个图
直接上代码
js部分
import moment from 'moment' //引入js日期处理类库
import {
Message
} from 'element-ui'
/**
* @param {object} opts
*
* callback:表单校验里面的回调函数
*
* start:日期时间段的开始日期所在字段
*
* end:日期时间段的结束日期所在字段
*
* vm:校验所在 this
*
*
* 非必传
* errMsg:报错提示语
*
* than:默认 大于等于,1:大于;
*
* obj:字段所在对象,即表单绑定的对象,默认 form
*
* formRef:表单vm组件,用于获取refs对象
*
* clearValidate:需要清除校验的字段,prop 绑定的字段,如果是表格嵌套表单,不支持
*/
export function validateDate(opts = {}) {
if (!opts.start || !opts.end || !opts.callback || !opts.vm) return;
if (!opts.obj) opts.obj = opts.vm.form;
if (!opts.formRef) opts.formRef = 'form';
if (opts.obj[opts.end] && opts.obj[opts.start]) {
let endDate = moment(opts.obj[opts.end]).valueOf(),
startDate = moment(opts.obj[opts.start]).valueOf();
// console.log(startDate, endDate, opts.errMsg);
if (!opts.than) endDate >= startDate opts.callback() : opts.callback(new Error(opts.errMsg || '结束日期需大于等于开始日期'))
else if (opts.than == 1) endDate > startDate opts.callback() : opts.callback(new Error(opts.errMsg || '结束日期需大于开始日期'))
// 移除校验字段
if (opts.clearValidate && opts.formRef) opts.vm.$refs[opts.formRef].clearValidate(opts.clearValidate)
} else opts.callback()
}
// 用于非 表单验证 数据校验
export function submitValidateDate(opts = {}) {
if (!opts.start || !opts.end || !opts.obj) opts.callback();
if (opts.obj[opts.end] && opts.obj[opts.start]) {
let endDate = moment(opts.obj[opts.end]).valueOf(),
startDate = moment(opts.obj[opts.start]).valueOf();
// console.log(startDate, endDate, opts.errMsg);
if (!opts.than && startDate > endDate) {
Message.error(opts.errMsg || '结束日期需大于等于开始日期')
return
} else if (opts.than == 1 && startDate >= endDate) {
Message.error(opts.errMsg || '结束日期需大于开始日期')
return
}
}
opts.callback()
}
vue 部分
<template>
<div class="person-off-work-list">
<el-card class="card-box">
<span>查询条件</span>
<!-- 使用 Form 组件:行内表单 -->
<el-form inline :model="form" :rules="rules" class="fee-form" ref="form">
<el-row>
<el-form-item prop="startDate">
<el-date-picker v-model="form.startDate" v-date-format="{
obj: 'form',
modelName: 'startDate',
format: 'yyyy-MM-DD',
}" format="yyyy-MM-dd" value-format="yyyy-MM-dd" :picker-options="pickerOptionsStart()" type="date"
placeholder="开始日期">
</el-date-picker>
</el-form-item>
<el-form-item prop="endDate">
<el-date-picker v-model="form.endDate" type="date" placeholder="结束日期" v-date-format="{
obj: 'form',
modelName: 'endDate',
format: 'yyyy-MM-DD',
}" format="yyyy-MM-dd" value-format="yyyy-MM-dd" :picker-options="pickerOptionsEnd()">
</el-date-picker>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSearch" :disabled="isLoading">查询</el-button>
</el-form-item>
</el-row>
</el-form>
</el-card>
</el-card>
</div>
</template>
<script>
import { validateDate } from "../../../utils/mixins/validateDate";
export default {
data() {
return {
rules: {
startDate: [
{
validator: (rule, value, callback) =>
validateDate({
callback,
start: "startDate",
end: "endDate",
vm: this,
errMsg: "开始日期需小于等于结束日期",
// than: 1,
obj: that.form,
formRef: "form",
clearValidate: "endDate",
}),
trigger: ["change", "blur"],
},
],
endDate: [
{
validator: (rule, value, callback) =>
validateDate({
callback,
start: "startDate",
end: "endDate",
vm: this,
errMsg: "结束日期需大于等于开始日期",
// than: 1,
obj: that.form,
formRef: "form",
clearValidate: "startDate",
}),
trigger: ["change", "blur"],
},
],
},
// 查询form
form: {},
// 用于保存加载状态
isLoading: false,
};
},
methods: {
/**
* 【查询】按钮触发
*/
onSearch() {
this.$refs.form.validate((valid) => {
console.log(valid);
valid && this.loadResources({ currentPage: 1 });
});
},
/**
* 加载table中数据
*/
loadResources(data = {}) {
// 组合发起请求参数
let obj = Object.assign(
{
currentPage: this.currentPage,
pageSize: this.pageSize,
},
this.form,
data
);
// 开始加载数据
this.tableData = [];
this.isLoading = true;
// 发起请求
aaa(obj).then((res) => {
if (res.code === 200) {
// 获取数据
this.tableData = res.data.aaaList;
this.currentPage = res.data.currentPage || obj.currentPage;
this.pageSize = obj.pageSize || this.pageSize;
this.total = res.data.totalSize || this.total;
}
})
.catch((err) => {
// 报错处理
this.currentPage = 1;
this.total = 0;
})
.finally(() => {
// 请求成功处理
this.isLoading = false;
});
},
},
};
</script>
/**
* 【查询】按钮触发
*/
// 这是第二种方法的事例
onSearch() {
submitValidateDate({
callback: () => this.loadResources({ currentPage: 1, ...this.form }),
obj: this.form,
start: "startDate",
end: "endDate",
errMsg: "结束年月需大于等于开始年月",
});
},
代码简述
- 看 js
- 上面都有备注,使用 moment 来进行日期格式处理,需要注意 moment 和 其他日期处理的插件对日期的格式是不同的;
- 采用 options 对象来进行传参,这样传参可控制,拿取的时候也方便,之前写公共方法的时候,挨个传参数,自己用起来都自闭,就更不要说别人了;
- callback 属性:element form 表单支持自定义校验规则,这个 callback 就是自定义校验规则里面的 callback 参数,不明白的可以去看一下文档,不管校验通不通过,都要执行该回调,因为不执行,不会报错,但是校验会卡在那里,此错误很难查出来;
- obj:字段所在对象(即对象引用),即表单绑定的对象,默认 form
- clearValidate:需要清除校验的字段,prop 绑定的字段,在触发方法之后,要清除掉另一个字段的校验
- 看 vue
- validateDate 方法适用 form 表单校验,submitValidateDate 方法适用数据提交之前的阻断;
- submitValidateDate 方法的 callback 是数据校验通过之后执行需要的方法,字段名一样,但是意义不同;
- validateDate 方法写在自定义校验中,在表单组件的 validate 方法中会自动执行,非必填字段也会校验住
- 如果 vm 参数的数据不对,可以使用另一种方法:在组件的 script 标签中定义 that,然后在组件初始化的时候进行 that = this 操作赋值,再对 vm 赋值 that 即可;
说明
- element 的日期组件在默认情况下是可以进行输入的,但是输入的内容在配置了 picker-options 中的 disabledDate 范围校验之后,并不会对数据进行处理,那就只能自己进行操作了,如果嫌麻烦,可以设置禁止输入,因为手动输入实在太麻烦了;
- 校验方法还挺长的,要是每一次都 cv 一遍,就太离谱了;
仙人指路
- moment.js 获取 昨天、今天、上周、本周、上月、本月、上季度、本季度、去年 时间段,并集成到 vue Ant Design a-range-picker 日期选择器中
- vue Ant Design Select 选择框输入搜索已有数据 mixin
- vue + Ant Design 表格多选 mixin
- 中文按拼音首字母排序
- 数组方法
- 两个数组中相同元素、大数组中不包含小数组部分、一行代码数组去重
- vue + Ant Design 表格多选 mixin
- vue 中父子组件通信 js 引用的作用
- Vue组件通信—provide/inject