参照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>