实现表单的双向绑定和校验控制逻辑

**实现表单的双向绑定和校验控制逻辑 **

1. 需求

         - 实现input表单的双向绑定
	     - 实现表单的输入校验,以及校验信息提示
	     - 实现表单提交时的整体校验

类似element表单提交校验

在这里插入图片描述

2. input表单的双向绑定 v-modal语法糖
输⼊框Kinput 组件

<template>
  <div>
    <input :type="type" :value="value" @input="onInput" v-bind="$attrs" />
  </div>
</template>

<script>
export default {
  props: {
    type: {
      type: String,
      default: "text",//表单类型
    },
    value: {
      type: String,
      default: "", //表单值
    },
  },
  methods: {
    onInput(e) {
      this.$emit("input", e.target.value);//触发  input事件回调值    
    },
  },
};
</script>

引用组件

 <k-input
          type="text"
          v-model="model.username"
          placeholder="输入"
        ></k-input>

3. 实现表单label表单以及表单校验信息显示

*表单项KFormItem*
  • label标签添加

  • 载体,输⼊项包起来

  • 校验执⾏者,显示错误

在Kinput 组件中在input事件中触发KFormItem回调校验方法

 onInput(e) {
      this.$emit("input", e.target.value);
      this.$parent.$emit("validate");//触发校验   
    },
     // Kinput已挂载,可以监听校验事件
    this.$on("validate", () => {
      this.handleValidate();
    });

组件代码块

<template>
  <div class="formitem">
    <label v-if="label">{{ label }}</label>
    <slot></slot>
    <p v-if="error">{{ error }}</p>
    <!-- <p>{{ this.form.rules[this.prop] }}</p> -->
  </div>
</template>

<script>
import Validator from "async-validator";//校验js库
export default {
  inject: ["form"],//inject接收Kform的provide传值
  data() {
    return {
      error: "",
    };
  },
  props: {
    label: {
      type: String,
      default: "",//label标签名
    },
    prop: {
      type: String,//当前校验字段
      default: "",
    },
  },
  mounted() {
    // Kinput已挂载,可以监听校验事件
    this.$on("validate", () => {
      this.handleValidate();
    });
  },
  methods: {
    handleValidate() {
      const value = this.form.model[this.prop];//当前表单值
      const rule = this.form.rules[this.prop];//当前表单字段校验规则
      //校验方法是使用async-validator库 校验  
      const validator = new Validator({ [this.prop]: rule });
      return validator.validate({ [this.prop]: value }, (error) => {//返回promise对象
        if (error) {
          // 显示错误信息
          this.error = error[0].message;
        } else {
          // 校验通过清除错误
          this.error = "";
        }
      });
    },
  },
};
</script>

<style lang="scss" scoped>
.formitem {
  // display: flex;
  // justify-content: center;
}
</style>

引用组件
 <k-form-item label="用户名" prop="username">
        <k-input
          type="text"
          v-model="model.username"
          placeholder="输入"
        ></k-input>
      </k-form-item>

3.表单KForm

  • 载体,输⼊数据model,校验规则rules
  • 校验validate
<template>
  <div>
    <slot></slot>
  </div>
</template>

<script>
export default {
  provide() {
    return {
      form: this,
    };
  },
  props: {
    model: {
      type: Object,
      required: true,
    },//所以表单数据集合
    rules: Object,//字段校验规则集合
  
  },
  mounted() {
    // console.log(this.$children);
  },
  methods: {
    validate(cb) {//cb是回调函数
      const child = this.$children;
      const results = child
        .filter((v) => v.prop)
        .map((_v) => {
          return _v.handleValidate();//收集KFormItem校验promise
        });
      //   console.log(results);
      Promise.all(results)
        .then(() => cb(true))
        .catch(() => cb(false));
    },
  },
};
</script>

<style lang="scss" scoped></style>

组件引用

 <k-from :model="model" :rules="rules" ref="loginItem">
      <k-form-item label="用户名" prop="username">
        <k-input
          type="text"
          v-model="model.username"
          placeholder="输入"
        ></k-input>
      </k-form-item>
      <k-form-item label="密码" prop="password">
        <k-input type="password" v-model="model.password"></k-input>
      </k-form-item>
      <k-form-item>
        <button @click="submitFrom">提交</button>
      </k-form-item>
    </k-from>

校验回调函数

submitFrom() {
      this.$refs.loginItem.validate((isValid) => {
        console.log(isValid);
        this.$notice({
          title: "提示信息",
          message: isValid ? "校验成功通过" : "不通过",
        });
      });
    },

model和rules集合

 data() {
    return {
      model: {
        username: "llgtfoo",
        password: "111",
      },
      rules: {
        username: [{ required: true, message: "用户名为必填项" }],
        password: [{ required: true, message: "密码必填项" }],
      },
    };
  },
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值