VUE表单双向绑定及校验原理

本文深入探讨了Vue.js中双向绑定的实现原理,详细解释了如何通过监听input事件实现父组件与子组件间的数据同步。同时,文章还介绍了输入校验的机制,包括校验组件结构设计、数据模型绑定及规则传递方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、双向绑定原理

就是绑定value值,监听input事件
即,父组件通过props传递value值,子组件通过监听Input事件来
实时将value值通过$emit传递给父组件。
<div>
    <input :type="type" :value="value" @input="onInput">
</div>
export default {
        props:{
            value:{
                type:String,
                default:''
            },
            type:{
                type:String,
                default:'text'
            }
        },
        methods: {
            onInput(e) {
                let value = e.target.value;
                this.$emit('input',value);
                // 当值发生改变后
                // 给父级组件发送一个事件
                this.$parent.$emit('validate');
            }
        },
}

2、输入校验原理

首先确定校验组件结构,主要有三层:

  • 最外层负责绑定数据模型和校验规则;
  • 中间层负责校验和显示错误;
  • 最底层负责改变数据同时,将数据变化实时发送给父组件;
页面布局:
<k-form :model="model" :rules="rules" >
   <k-form-item label="用户名" prop="username">
       <k-input v-model="model.username"></k-input>
   </k-form-item>
   <k-form-item label="密码" prop="password">
       <k-input v-model="model.password" type="password"></k-input>
    </k-form-item>
</k-form>
脚本部分:
data() {
    return {
      value:'',
      model: { username: "tom", password: "" },
      rules: {
        username: [
          { required: true, message: "请输入用户名" },
          {min: 6,max:10,message:'请输入6~10的用户名'}
        ],
        password: [
          { required: true, message: "请输入密码" }
        ],
      }
    };
  }
};

这里需要明确两个问题?

  1. FormItem是怎么知道执行校验的,它是怎么知道Input状态的?它是怎么获得对应数据模型的?
1、子组件通过this.$parent.$emit('validate');来给父组件绑定一个事件实例,
父组件通过$on来获取到这个事件,从而执行methods方法。
注意:$on必须放在mounted中执行,且只能监听自身方法,通过this.$emit的方法无法直接监听。
2、通过inject:['kForm']可以直接取用父组件的数据;
<template>
    <div>
        <label for="">{{label}}</label>
        <div>
            <slot></slot>
            <p v-if="errStatus">{{errMessage}}</p>
        </div>
    </div>
</template>

<script>
    // 引入校验类
    import Schema from 'async-validator'
    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 = '';
                    }
                })

            }
        },
    }
</script>
  1. Form是怎么进行全局校验的?它用什么办法把数据模型和校验规则传递给内部组件?
1、只需要用插槽将中间校验层插入进来即可;
2、可以通过provide将当前this保存,下面任意子组件都可以通过inject取到。
这样就可以直接获取到它所绑定的数据模型和校验规则。
<template>
    <form>
        <slot></slot>
    </form>
</template>
<script>
    export default {
        provide(){
            return {
                kForm: this
            }
        },
        props:{
            model:{
                type:Object,
                required:true
            },
            rules:{
                type:Object
            }
        }
    }
</script>

知识点:

provide and inject
只要父组件定义了provide,子组件可以直接通过inject取到值
优点:无视层级,直接取用,单向数据流中的王者!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值