先上個圖

image.png
直接上代碼
js部分
import moment from 'moment' //引入js日期處理類庫
import {
Message
} from 'element-ui'
/**
* @param {object} opts
*
* callback:表單校驗里面的回調(diào)函數(shù)
*
* start:日期時間段的開始日期所在字段
*
* end:日期時間段的結(jié)束日期所在字段
*
* 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 || '結(jié)束日期需大于等于開始日期'))
else if (opts.than == 1) endDate > startDate ? opts.callback() : opts.callback(new Error(opts.errMsg || '結(jié)束日期需大于開始日期'))
// 移除校驗字段
if (opts.clearValidate && opts.formRef) opts.vm.$refs[opts.formRef].clearValidate(opts.clearValidate)
} else opts.callback()
}
// 用于非 表單驗證 數(shù)據(jù)校驗
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 || '結(jié)束日期需大于等于開始日期')
return
} else if (opts.than == 1 && startDate >= endDate) {
Message.error(opts.errMsg || '結(jié)束日期需大于開始日期')
return
}
}
opts.callback()
}
vue 部分
<template>
<div class="person-off-work-list">
<el-card class="card-box">
<span>查詢條件</span>
<!-- 使用 Form 組件:行內(nèi)表單 -->
<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="開始日期" style="width: 250px">
</el-date-picker>
</el-form-item>
<el-form-item prop="endDate">
<el-date-picker v-model="form.endDate" type="date" placeholder="結(jié)束日期" style="width: 250px" 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: "開始日期需小于等于結(jié)束日期",
// 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: "結(jié)束日期需大于等于開始日期",
// than: 1,
obj: that.form,
formRef: "form",
clearValidate: "startDate",
}),
trigger: ["change", "blur"],
},
],
},
// 查詢form
form: {},
// 用于保存加載狀態(tài)
isLoading: false,
};
},
methods: {
/**
* 【查詢】按鈕觸發(fā)
*/
onSearch() {
this.$refs.form.validate((valid) => {
console.log(valid);
valid && this.loadResources({ currentPage: 1 });
});
},
/**
* 加載table中數(shù)據(jù)
*/
loadResources(data = {}) {
// 組合發(fā)起請求參數(shù)
let obj = Object.assign(
{
currentPage: this.currentPage,
pageSize: this.pageSize,
},
this.form,
data
);
// 開始加載數(shù)據(jù)
this.tableData = [];
this.isLoading = true;
// 發(fā)起請求
aaa(obj).then((res) => {
if (res.code === 200) {
// 獲取數(shù)據(jù)
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>
/**
* 【查詢】按鈕觸發(fā)
*/
// 這是第二種方法的事例
onSearch() {
submitValidateDate({
callback: () => this.loadResources({ currentPage: 1, ...this.form }),
obj: this.form,
start: "startDate",
end: "endDate",
errMsg: "結(jié)束年月需大于等于開始年月",
});
},
代碼簡述
- 看 js
- 上面都有備注,使用 moment 來進行日期格式處理,需要注意 moment 和 其他日期處理的插件對日期的格式是不同的;
- 采用 options 對象來進行傳參,這樣傳參可控制,拿取的時候也方便,之前寫公共方法的時候,挨個傳參數(shù),自己用起來都自閉,就更不要說別人了;
- callback 屬性:element form 表單支持自定義校驗規(guī)則,這個 callback 就是自定義校驗規(guī)則里面的 callback 參數(shù),不明白的可以去看一下文檔,不管校驗通不通過,都要執(zhí)行該回調(diào),因為不執(zhí)行,不會報錯,但是校驗會卡在那里,此錯誤很難查出來;
- obj:字段所在對象(即對象引用),即表單綁定的對象,默認 form
- clearValidate:需要清除校驗的字段,prop 綁定的字段,在觸發(fā)方法之后,要清除掉另一個字段的校驗
- 看 vue
- validateDate 方法適用 form 表單校驗,submitValidateDate 方法適用數(shù)據(jù)提交之前的阻斷;
- submitValidateDate 方法的 callback 是數(shù)據(jù)校驗通過之后執(zhí)行需要的方法,字段名一樣,但是意義不同;
- validateDate 方法寫在自定義校驗中,在表單組件的 validate 方法中會自動執(zhí)行,非必填字段也會校驗住
- 如果 vm 參數(shù)的數(shù)據(jù)不對,可以使用另一種方法:在組件的 script 標簽中定義 that,然后在組件初始化的時候進行 that = this 操作賦值,再對 vm 賦值 that 即可;
說明
- element 的日期組件在默認情況下是可以進行輸入的,但是輸入的內(nèi)容在配置了 picker-options 中的 disabledDate 范圍校驗之后,并不會對數(shù)據(jù)進行處理,那就只能自己進行操作了,如果嫌麻煩,可以設(shè)置禁止輸入,因為手動輸入實在太麻煩了;
- 校驗方法還挺長的,要是每一次都 cv 一遍,就太離譜了;
仙人指路
- moment.js 獲取 昨天、今天、上周、本周、上月、本月、上季度、本季度、去年 時間段,并集成到 vue Ant Design a-range-picker 日期選擇器中
- vue Ant Design Select 選擇框輸入搜索已有數(shù)據(jù) mixin
- vue + Ant Design 表格多選 mixin
- 中文按拼音首字母排序
- 數(shù)組方法
- 兩個數(shù)組中相同元素、大數(shù)組中不包含小數(shù)組部分、一行代碼數(shù)組去重
- vue + Ant Design 表格多選 mixin
- vue 中父子組件通信 js 引用的作用
- Vue組件通信—provide/inject