日期组件范围互相校验公共方法抽取

先上个图

image.png

直接上代码

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="开始日期" style="width: 250px">
            </el-date-picker>
          </el-form-item>
          <el-form-item prop="endDate">
            <el-date-picker v-model="form.endDate" type="date" placeholder="结束日期" 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: "开始日期需小于等于结束日期",
                // 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
    1. 上面都有备注,使用 moment 来进行日期格式处理,需要注意 moment 和 其他日期处理的插件对日期的格式是不同的;
    2. 采用 options 对象来进行传参,这样传参可控制,拿取的时候也方便,之前写公共方法的时候,挨个传参数,自己用起来都自闭,就更不要说别人了;
    3. callback 属性:element form 表单支持自定义校验规则,这个 callback 就是自定义校验规则里面的 callback 参数,不明白的可以去看一下文档,不管校验通不通过,都要执行该回调,因为不执行,不会报错,但是校验会卡在那里,此错误很难查出来;
    4. obj:字段所在对象(即对象引用),即表单绑定的对象,默认 form
    5. clearValidate:需要清除校验的字段,prop 绑定的字段,在触发方法之后,要清除掉另一个字段的校验
  • 看 vue
    1. validateDate 方法适用 form 表单校验,submitValidateDate 方法适用数据提交之前的阻断;
    2. submitValidateDate 方法的 callback 是数据校验通过之后执行需要的方法,字段名一样,但是意义不同;
    3. validateDate 方法写在自定义校验中,在表单组件的 validate 方法中会自动执行,非必填字段也会校验住
    4. 如果 vm 参数的数据不对,可以使用另一种方法:在组件的 script 标签中定义 that,然后在组件初始化的时候进行 that = this 操作赋值,再对 vm 赋值 that 即可;

说明

  1. element 的日期组件在默认情况下是可以进行输入的,但是输入的内容在配置了 picker-options 中的 disabledDate 范围校验之后,并不会对数据进行处理,那就只能自己进行操作了,如果嫌麻烦,可以设置禁止输入,因为手动输入实在太麻烦了;
  2. 校验方法还挺长的,要是每一次都 cv 一遍,就太离谱了;

仙人指路

  1. moment.js 获取 昨天、今天、上周、本周、上月、本月、上季度、本季度、去年 时间段,并集成到 vue Ant Design a-range-picker 日期选择器中
  2. vue Ant Design Select 选择框输入搜索已有数据 mixin
  3. vue + Ant Design 表格多选 mixin
  4. 中文按拼音首字母排序
  5. 数组方法
  6. 两个数组中相同元素、大数组中不包含小数组部分、一行代码数组去重
  7. vue + Ant Design 表格多选 mixin
  8. vue 中父子组件通信 js 引用的作用
  9. Vue组件通信—provide/inject
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351