preface

Implementing a form component similar to Element-UI allows us to see the process of developing a generic component.

Effect: Element form

Generic form component

  • Index
<template> <el-form :model="model" :reules="rules" ref="loginForm"> <el-form-item prop="username"> <el-input t Ype ="text" v-model="model.username" plachedor=" please enter username" ></el-input> </el-form-item> <el-form-item prop="password"> <el-input type="password" V-model ="model.password" plachedor=" Please input password" ></el-input> </el-form-item> <el-form-item> <button </button> </el-form-item> </el-form> </template> <script> import elForm from 'el-form' import elFormItem from 'el-form-item' import elInput from 'el-input.vue' export default{ components:{ elForm, ekFormItem, ElInput}, data(){return{model:{username:"", password:""}, rules:{username:[{required:true,message:" username must be entered "}], Password :[{required:true,message:" Password must be entered "}]}}}, Methods :{login(){this.$refs.loginform. Validate (isValid=>{if(isValid){alert(" login failed ")}})}}} </script>Copy the code
  • El-form Specifies data and verification rules
<template> <div> <slot></slot> </div> </template> <script> export default{provide(){return{form:this //provide. The overall content of the transfer of reference, convenient management. Because the object passed in is reactive, the receiver is also reactive. }}, props:{model:{type:Object, required:true}, rules:Object}, methods:{cb is a callback function for the whole form, validate(cb){ Const tasks = this.$children.filter(item=>item.prop).map(item=>item.validate()) Using Promise. Promise all concurrent processing. All (tasks). Then (() = > {cb (true)}). The catch (() = > {cb (false)})}}} < / script >Copy the code
  • el-form-item
<template> <div> <lable v-if="label">{{label}}</label> <slot></slot> <p v-if="error">{{error}}</p> </div> </template> <script> import Validator from 'async-validator' NPM install Async-validator export default{ Inject :['form'], props:{label:{type:String, default:""}, prop:{type:String//prop is used to obtain the content data of the object}}, Data () {return {error: ""}}, mounted () {/ / listen to check this. $on (" validate", () = > {enclosing the validate ()})}, Methods :{validate(){const value = this.form.model[this.prop]// Const rules = this.form.rules[this.prop]// Const validator = new Validator({[this.prop]:rules}) const Validator = new Validator({[this.prop]:rules} validator.validate({[this.prop]:value},errors=>{ if(errors){ this.error = errors[0].message }else{ this.error = "" } }) } } } </script>Copy the code
  • el-input
<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:"" } }, Methos :{onInput(e){this.$emit("input",e.target.value) this.$parent.$emit("validate") // The sender and listener of the event must be the same. Because the content of the parent component is distributed using slot, use $parent to point to the parent. $parent FormItem}}} </script>Copy the code

Pop-up components

Components such as pop-ups are unique in that they exist independently of the current VUE instance, usually mounted on the body; They are created dynamically through JS and do not need to be declared in any component.