参照element ui 表单组件,实现一个简易的登录表单校验。
App.vue
<template>
<div id="app">
{{value}}
<k-input :value="value" @input="setVal"></k-input>
<hr/>
<k-form :model="userInfo" :rules="rules">
<k-form-item label="用户名" prop="username">
<k-input v-model="userInfo.username"></k-input>
</k-form-item>
<k-form-item label="密码" prop="password">
<k-input v-model="userInfo.password" type="password"></k-input>
</k-form-item>
</k-form>
</div>
</template>
<script>
import kInput from "./components/Input.vue";
import KFormItem from "./components/FormItem.vue";
import KForm from "./components/Form.vue";
export default {
name: "app",
components: {
kInput,
KFormItem,
KForm
},
data() {
return {
value: "gg",
userInfo: {
username: "",
password: ""
},
rules: {
username: [
{ required: true, message: "请输入用户名" },
{ min: 3, max: 5, message: "长度在 3 到 5 个字符" }
],
password: [{ required: true, message: "请输入密码" }]
}
};
},
methods: {
setVal(val) {
this.value = val;
}
}
};
</script>
Input.vue
<!-- input -->
<template>
<div>
<input :type="type" :value="value" @input="onInput" />
</div>
</template>
<script>
export default {
props: {
value: {
type: String
},
type: {
type: String,
default: "text"
}
},
components: {},
data() {
return {};
},
computed: {},
methods: {
onInput(e) {
let value = e.target.value;
this.$emit("input", value);
this.$parent.$emit("validate")
}
}
};
</script>
<style lang='less' scoped>
</style>
FormItem.vue
<!-- FormItem -->
<template>
<div>
<label :prop="prop">{{label}}</label>
<slot></slot>
<p v-if="errorStatus">{{errorMsg}}</p>
</div>
</template>
<script>
import Schema from "async-validator";
export default {
props: {
label: {
type: String
},
prop: {
type: String
}
},
inject: ["Form"],
components: {},
data() {
return {
errorStatus: false,
errorMsg: ""
};
},
mounted() {
this.$on("validate",this.validator);
},
methods: {
validator() {
let rules = this.Form.rules[this.prop];
let value = this.Form.model[this.prop];
let descriptor = { [this.prop]: rules };
let schema = new Schema(descriptor);
schema.validate({[this.prop]:value},errors=>{
if(errors){
this.errorStatus = true;
this.errorMsg = errors[0].message
}else{
this.errorStatus = false;
this.errorMsg = ""
}
})
}
}
};
</script>
<style lang='less' scoped>
</style>
Form.vue
<!-- Form -->
<template>
<div>
<form :model="model" :rules="rules">
<slot></slot>
</form>
</div>
</template>
<script>
export default {
props: {
model: {
type: Object,
required: true
},
rules: Object
},
provide() {
return {
Form: this
};
},
components: {},
data() {
return {};
},
computed: {},
methods: {}
};
</script>
<style lang='less' scoped>
</style>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。