vue 组件设计:实现Form, Formltem, Input及其原理实现

vue 组件设计:实现Form, Formltem, Input

需要思考的几个问题?

  1. Input是自定义组件,它是怎么实现双向绑定的?
  2. Formltem是怎么知道执行校验的,它是怎么知道Input状态的?它是怎么获得对应数据模型的?
  3. Form是怎么进行全局校验的?它用什么办法把数据模型和校验规则传递给内部组件?

实现 input

  • 实现自定义组件双向绑定功能
    v-model 是语法糖,实现自定义组件需要指定 :value @input即可
  • 值发生变化能通知FormItem 组件
        <input :type="type" :value="value" @input="onInput">
		
		 export default {
        props:{
            value:{
                type:String,
                default:''
            },
            type:{
                type:String,
                default:'text'
            }
        },
        methods: {
            onInput(e) {
                let value = e.target.value;
                //input 事件触发设置模型的值并通知父组件
                this.$emit('input',value);
                this.$parent.$emit('validate')
            }
        },
    }

实现 FormItem

  • input 预留插槽 solt
  • 能展示label 和校验信息
  • 能够进行校验
<div>
        <label for="">{{label}}</label>
        <div>
            <slot></slot> // 插槽
            <p v-if="errStatus">{{errMessage}}</p>
        </div>
 </div>

export default {
        inject:['kForm'],
        props:['label','prop'],
        data() {
            return {
                errMessage: '',
                errStatus: false
            }
        },
        mounted(){
            this.$on('validate',this.validator)
        },
        methods: {
            validator() {
                //有两个input!  一个用户名 一个密码
                const rules = this.kForm.rules[this.prop];
                const value = this.kForm.model[this.prop];
                // 描述对象
                const descriptor = {[this.prop]:rules};
                const schema = new Schema(descriptor);
                schema.validate({[this.prop]:value},errors =>{
                    if(errors){
                        this.errMessage = errors[0].message;
                        this.errStatus = true;
                    } else {
                        this.errMessage = '';
                        this.errStatus = '';
                    }
                })
            }
        },
    }

实现 Form

  • Form-item预留槽位
  • 将数据传递给后代便于它们访问数据模型和校验规则
    vue provide
  • provide && inject
 <form>
        <slot></slot>
  </form>

 export default {
        provide(){
            return {
                form: this //组件实例作为提供者,子代组件可方便获取
            }
        },
        props:{
            model:{
                type:Object,
                required:true
            },
            rules:{
                type:Object
            }
        }
    }

数据校验

  • 思路:校验发生在FormItem,他需要知道何时校验(让input去通知),还需要怎么去校验他(注入校验规则)
  • input通知校验
  • input 中的 oninput方法
 onInput(e) {
                let value = e.target.value;
                //input 事件触发设置模型的值并通知父组件
                this.$emit('input',value);
                //$parent指向 `FormItem`
                this.$parent.$emit('validate')
            }
  • FormItem监听校验通知,获取规则并执行校验
import Schema from 'async-validator'

 inject:['kForm'],//注入
mounted(){
//监听校验事件
            this.$on('validate',this.validator)
        },
methods: {
            validator() {
                //有两个input!  一个用户名 一个密码
                //获取对应 的FormItem校验规则
                const rules = this.kForm.rules[this.prop];
                //获取校验值
                const value = this.kForm.model[this.prop];
                 // 描述对象
                const descriptor = {[this.prop]:rules};
                //创建校验器
                const schema = new Schema(descriptor);
                schema.validate({[this.prop]:value},errors =>{
                    if(errors){
                    //将错误学习显示
                        this.errMessage = errors[0].message;
                        this.errStatus = true;
                    } else {
                    //校验通过
                        this.errMessage = '';
                        this.errStatus = '';
                    }
                })
                }
发布了76 篇原创文章 · 获赞 6 · 访问量 3470

猜你喜欢

转载自blog.csdn.net/weixin_43550660/article/details/103267280