**实现表单的双向绑定和校验控制逻辑 **
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: "密码必填项" }],
},
};
},