手动实现一个form组件
最近研究了一下element-ui,想着手动实现一下里面的form组件,贴个组件里面的代码
<el-form :model="ruleForm" status-icon :rules="rules" ref="ruleForm" label-width="100px" class="demo-ruleForm"> <el-form-item label="密码" prop="pass"> <el-input type="password" v-model="ruleForm.pass" autocomplete="off"></el-input> </el-form-item> <el-form-item label="确认密码" prop="checkPass"> <el-input type="password" v-model="ruleForm.checkPass" autocomplete="off"></el-input> </el-form-item> <el-form-item label="年龄" prop="age"> <el-input v-model.number="ruleForm.age"></el-input> </el-form-item> <el-form-item> <el-button type="primary" @click="submitForm('ruleForm')">提交</el-button> <el-button @click="resetForm('ruleForm')">重置</el-button> </el-form-item> </el-form>
该组件可以细分为三个组件form,formItem以及input组件,首先介绍input组件
- input组件:任务一是实现一个v-model的数据双绑定,即包含value的动态绑定以及input的实现
任务二是值发生改变的时候通知formItem组件
<template> <div> <input type="text" :value="value" @input="input"> </div> </template> <script> export default { props: { value: { type: String, default: "" } }, methods: { input(e) { let inputValue = e.target.value; this.$emit("input", inputValue); this.$parent.$emit('validate'); } } }; </script> <style lang="scss" scoped> </style>
2. FormItem组件: 任务一实现一个插槽
任务二显示label以及校验信息
任务三 对数据进行校验
<template> <div> <label :prop="prop">{{label}}</label> <slot></slot> <p>{{error}}</p> </div> </template> <script> //需要知道何时去校验 import Schema from "async-validator"; export default { inject: ["form"], props: { prop: { type: String, default: "" }, label: { type: String, default: "" } }, data() { return { error: '' } }, methods: { validate() { const rules = this.form.rules[this.prop]; //数组 const value = this.form.model[this.prop]; const descriptor = { [this.prop]: rules }; const schema = new Schema(descriptor); schema.validate({ [this.prop]: value }, errors => { if (errors) { this.error = errors[0].message; } else { this.error = ""; } }); } }, mounted() { this.$on("validate", this.validate); } }; </script> <style lang="scss" scoped> </style>
3. Form组件: 任务实现rules和model的传递,预留插槽
<template> <div> <form> <slot></slot> </form> </div> </template> <script> export default { provide() { return { form: this }; }, props: { rules: { type: Object }, model: { type: Object } } }; </script> <style lang="scss" scoped> </style>