日期組件范圍互相校驗公共方法抽取

先上個圖

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
    1. 上面都有備注,使用 moment 來進行日期格式處理,需要注意 moment 和 其他日期處理的插件對日期的格式是不同的;
    2. 采用 options 對象來進行傳參,這樣傳參可控制,拿取的時候也方便,之前寫公共方法的時候,挨個傳參數(shù),自己用起來都自閉,就更不要說別人了;
    3. callback 屬性:element form 表單支持自定義校驗規(guī)則,這個 callback 就是自定義校驗規(guī)則里面的 callback 參數(shù),不明白的可以去看一下文檔,不管校驗通不通過,都要執(zhí)行該回調(diào),因為不執(zhí)行,不會報錯,但是校驗會卡在那里,此錯誤很難查出來;
    4. obj:字段所在對象(即對象引用),即表單綁定的對象,默認 form
    5. clearValidate:需要清除校驗的字段,prop 綁定的字段,在觸發(fā)方法之后,要清除掉另一個字段的校驗
  • 看 vue
    1. validateDate 方法適用 form 表單校驗,submitValidateDate 方法適用數(shù)據(jù)提交之前的阻斷;
    2. submitValidateDate 方法的 callback 是數(shù)據(jù)校驗通過之后執(zhí)行需要的方法,字段名一樣,但是意義不同;
    3. validateDate 方法寫在自定義校驗中,在表單組件的 validate 方法中會自動執(zhí)行,非必填字段也會校驗住
    4. 如果 vm 參數(shù)的數(shù)據(jù)不對,可以使用另一種方法:在組件的 script 標簽中定義 that,然后在組件初始化的時候進行 that = this 操作賦值,再對 vm 賦值 that 即可;

說明

  1. element 的日期組件在默認情況下是可以進行輸入的,但是輸入的內(nèi)容在配置了 picker-options 中的 disabledDate 范圍校驗之后,并不會對數(shù)據(jù)進行處理,那就只能自己進行操作了,如果嫌麻煩,可以設(shè)置禁止輸入,因為手動輸入實在太麻煩了;
  2. 校驗方法還挺長的,要是每一次都 cv 一遍,就太離譜了;

仙人指路

  1. moment.js 獲取 昨天、今天、上周、本周、上月、本月、上季度、本季度、去年 時間段,并集成到 vue Ant Design a-range-picker 日期選擇器中
  2. vue Ant Design Select 選擇框輸入搜索已有數(shù)據(jù) mixin
  3. vue + Ant Design 表格多選 mixin
  4. 中文按拼音首字母排序
  5. 數(shù)組方法
  6. 兩個數(shù)組中相同元素、大數(shù)組中不包含小數(shù)組部分、一行代碼數(shù)組去重
  7. vue + Ant Design 表格多選 mixin
  8. vue 中父子組件通信 js 引用的作用
  9. Vue組件通信—provide/inject
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容