在我们日常的开发过程中,很经常的就会遇到需要做一个表单来提交数据。在做的过程中,各种必填required,各种杂七杂八的要求,就要写对应的rules去做验证,而这么做是停留在你使用ui框架提供的form及其验证的前提下来做才是简单的。否则,一堆的判断就够你焦头烂额了,更何况还有酷炫的需求等等。
  针对这个问题,如果你是用vue作为cli的话,可以考虑这几个插件,vuerify, v-vuerify-next, vee-validate……等等,而在提及的这些插件中,本人在开发时所用到的正是vuerifyv-vuerify-next配合使用,按照网上的说法,vee-validate就没配置成功,所以这个是果断放弃了。下面就总结一下遇到的问题吧^_^

1. 安装插件

  关于这一点,应该不用多说了

npm i vuerify -S
npm i v-vuerify-next -S

2. 引入插件

  在全局配置文件main.js中,写下以下代码,由于不需要花里胡哨的功能,所以只用了最简单的部分

import Vue from "vue";
import Vuerify from "vuerify";
import VuerifyDirector from "v-vuerify-next";

Vue.use(Vuerify);
//这里可以配置一些需要用到的全局规则等等
Vue.use(VuerifyDirector);

  引入后,视情况可在Vue.use(Vuerify, //加上自定义全局规则{} ),安装完插件,已自带有required,url等。


3. 修复 removeEventListener……的 bug

  这个bug主要是由v-vuerify-next所引发的,查了一下网上所说,报这个错的时候在于移除监听的时候缺少参数,根据这个线索,定位到 node_modules/v-vuerify-next/vuerify.common.js文件中的unbind字段,这里是取消绑定命令的执行方法。不知道是否是作者忘记加上的原因,这里少了一些东西,具体对比如下:

改之前
//...省略代码

unbind: function unbind(el) {
  el.removeEventListener("blur");
  el.removeEventListener("focus");
}

//...省略代码
改之后
//...省略代码

unbind: function unbind(el) {
  el.removeEventListener(
    "blur",
    function () {
      var err = vm.$vuerify.$errors[binding.value];

      if (err) {
        addClass(el, errorClass);
        vm.$emit("vuerify-invalid", binding.value, err);
      } else {
        removeClass(el, errorClass);
        vm.$emit("vuerify-valid", binding.value);
      }
    },
    true
  );
  el.removeEventListener(
    "focus",
    function () {
      removeClass(el, errorClass);
    },
    true
  );
}

//...省略代码

4. 使用

  以上问题都解决了之后,就可以开始来使用该插件了,vuerify是主要的处理,v-vuerify-next是才用了watch监听,传数据到其中进行判断,具体如下:

export default {
  data() {
    return {};
  },
  //这里主要写几个作为例子
  vuerify: {
    "form.name" : 'required',  //这里是全局自带的规则,也可以自定义一个
    "form.money": [     //多个要求的话使用数组包住,错误消息则会是一个数组
      { //验表单里的变量都要这样写,错误的话则为errors['form.money']类似
        test: function () {
          return this.validOrdinary(this.form.money);
        },
        message: "请输入",
      },
      {
        test: function () {
          return this.validVal(this.form.money);
        },
        message: "低于2000万元",
      },    //由于有多个消息提示,一般是互斥出现的,则可以采用errors['form.money'][0]这样就不会出现数组的框框了
    ],
    gaysTreatmentWay: {     //这里使用函数判断,主要是因为正则表达式判断不了undefined的变量
      test: function () {
        return this.validSimpleObj(this.gaysTreatmentWay);
      },
      message: "请选择",
    },
  otherFacilities: {
    test: function () {
      return this.validComplicateObj(this.otherFacilities);
    },
    message: '请输入'
  },
  computed: {
      errors() {
          return this.$vuerify.$errors;     //错误
      },

      pass() {
          return this.$vuerify.check(); //可传入字段名进行单独验证,不传则是验全部
      }
  },
  methods: {
    //验证一般变量
    validOrdinary(val) {
      return val != undefined && val != "";
    },

    //验证简单对象
    validSimpleObj(obj) {
      return obj.some((item) => item.check === true);
    },

    //验证复杂对象
    validComplicateObj(obj) {
      let noOne = obj.some((item) => item.check === true);
      if (noOne) {
        for (let item of obj) {
          if (item.check) {
            let flag = item.item.every((input) => input.value != "");
            if (!flag) return false;
          }
        }
        return true;
      } else {
        return false;
      }
    },
  },
};
<!--该插件主要监听blur 和 change事件,对原声组件和ui组件都是可以监听到的,举个例子-->
<!--只监听单个输入框-->
<van-field
  v-model="form.money"
  required
  type="number"
  label="钱"
  v-vuerify="form.money"
  placeholder="请输入钱数"
  clearable
  colon
  maxlength="9"
>
  <template #button>
    <span>(m<sup>3</sup>/d)</span>
  </template>
</van-field>

<!--复杂监听-->
<div style="min-height:100px;">
  <p style="text-align:center;">
    <span class="impo">*</span>测试字段(mg/L)
    <span v-if="errors.testVal" style="color:red;padding-left:10px;"
      >{{errors.testVal}}</span
    >
  </p>
  <div class="waste-water">
    <div v-for="(per, index) in testVal" :key="index" class="per-item">
      <template v-for="(perItem, perIndex) in per.item">
        <p :key="perIndex+10">
          <el-checkbox
            v-model="per.check"
            v-vuerify="testVal"
            @change="()=>{
                                  perItem.value = ''
                                }"
            >{{perItem.label}}</el-checkbox
          >
          <el-input
            style="border-bottom:solid 1px black; width: 50px;"
            size="mini"
            v-model="perItem.value"
            v-vuerify="testVal"
            :readonly="!per.check"
          ></el-input>
        </p>
      </template>
    </div>
  </div>
</div>

5. 使用体会

  就目前看来,修复了第三个的bug之后,表现正常。面对这种很多变量的表单,如果不是用ui框架特有的有带验证的组件去做的话,可以考虑使用该插件来进行处理,例如直接使用table来模拟表单的话,就可以使用该插件。
  虽然是换汤不换药,本质的判断还是要自己来写,但是对比自己写的判断,可能会更加优雅一点?(⊙o⊙)?,而且可以实时watch,对于想摆放一些错误提示上来也比较简单(⊙o⊙)?,这是本人目前使用的体验,当然,如果你有更好的方法来处理这些复杂的表单,欢迎留言区评论指教,不胜感激

  • alipay
  • wechat

一个好奇的人