美文网首页
Vue实现表单验证组件和弹框组件

Vue实现表单验证组件和弹框组件

作者: key君 | 来源:发表于2019-09-30 01:15 被阅读0次

    具体代码连接

    https://github.com/iosKey/Web

    核心代码

    弹框组件通过实例化来使用 create.js
    export default function(Component,props){
        // 创建一个vue.Component实例并渲染
        const vm = new Vue({
            //createElement函数
            render(h){
                //渲染函数 return v-dom
                return h(Component,{props})
            }
        }).$mount()
    
        // 挂载
        //获取真实dom挂载到body上
        document.body.appendChild(vm.$el)
    
        //or创建实例的第二种方式 返回组件的构造函数
        // const Ctor = Vue.extend(Component);
        // const comp =  new Ctor({propsData: props})
        // document.body.appendChild(comp.$el)
      
        //获取组件实例
        const comp = vm.$children[0];
        // 销毁
        comp.remove = () => {
            //移除dom
            document.body.removeChild(vm.$el)
            //销毁实例
            vm.$destroy()
        }
        return comp
    }
    
    //创建弹窗实例
                    const comp = create(Notice,{
                        title: '提示',
                        message: isValidate ? "请求登录": "校验失败",
                        duration: 3000
                    })
                    comp.show()
    
    表单组件
    KInput.vue 双向绑定 派发input事件
    <!-- 双绑 :value @input -->
          <!-- 绑定value属性 使用的是父组件传入的参数 实现input事件 派发事件 固定写法 -->
          <!-- v-bind有个特殊功能 是对象展开 $attrs是特性 可以利用传值  $attrs是对象
           v-bind会把里面的键值对用等号连接 作为属性去赋值-->
          <input :type="type" :value="value" @input="onInput" v-bind="$attrs">
    
    
    onInput(e){
                // 派发消息input 和 输入框的值作为参数
                this.$emit('input',e.target.value);
                // sync派发
                // this.$emit('update:value',e.target.value);
    
    
                //通知校验 因为当前组件是在插槽里所以不能用emit派发事件
                //所以让父组件KFormItem去派发 然后父组件可以自己监听
                this.$parent.$emit('validate')
            }
    
    KFormItem.vue 插槽插入input组件 显示错误信息
    <template>
        <div>
            <!-- 父组件传值 -->
            <label v-if="label">
                {{label}}
            </label>
            <slot></slot>
            <!-- 错误信息 是自身的属性 -->
            <p v-if="error">{{error}}</p>
        </div>
    </template>
    
    接受派发的input事件 对每个input进行输入时校验 用到schema插件
    //当输入时 子类通过$parent派发的 本身负责接收然后 校验
            validate(){
                //获取输入框内容 model是form表单传进来的 model的key是父组件传进来的属性
                const value = this.form.model[this.prop]
                const rule = this.form.rules[this.prop]
                
                //传入对象 [username]:规则数组
                const schema = new Schema({[this.prop]:rule})
                //传入对象 [username]:输入框的值
                //返回的是promise
                return schema.validate({[this.prop]:value},errors => {
                    if(errors){
                        //是个数组
                        this.error = errors[0];
                        console.log(errors[0]);
                        
                    }else{
                        this.error = '';
                    }
                })
            } 
    
    KForm.vue 把三个KFormItem插入
    <template>
      <div>
        <slot></slot>
      </div>
    </template>
    
    做全局校验
    //做全局校验 cb是传进来的函数
            validate(cb){
                //获取校验项
                //首先拿到KForm的子元素 拿去遍历 得到的是每一个KFormItem 让它执行validate方法
                //返回的是一个promise数组
                const tasks = this.$children
                .filter(item => item.prop)//只留下有prop属性的
                .map(item => item.validate())
                //Promise.all所有promise成功才算成功
                Promise.all(tasks)
                .then(()=>cb(true))
                .catch(()=> cb(false))
            }
    
    index.vue 组合组件
    <template>
        <div>
            <h2>KForm Test</h2>
            <KForm :model="model" :rules="rules" ref="loginForm"> 
                <kFormItem label="用户名" prop="username">
                    <!-- v-model把可以看作:value 和 @input的语法糖 把model.username作为value传入 -->
                    <KInput v-model="model.username" placeholder="abc"/>
                    <!-- 这里还可以写成sync修饰符 -->
                    <!-- <KInput :value.sync="model.username"/> -->
                </kFormItem>
                <kFormItem label="密码" prop="password">
                    <KInput type="password" v-model="model.password"/>
                </kFormItem>
                <kFormItem>
                    <button @click="submit">登录</button>
                </kFormItem>
            </KForm>
            {{model}}
        </div>
    </template>
    
    通过获取表单实例 直接调用验证方式
     //登录点击
            submit(){
                this.$refs.loginForm.validate(isValidate =>{
                    //创建弹窗实例
                    const comp = create(Notice,{
                        title: '提示',
                        message: isValidate ? "请求登录": "校验失败",
                        duration: 3000
                    })
                    comp.show()
                    // if(isValidate){
                    //     alert('登录中');
                    // }else{
                    //     alert('错误');
                    // }
                })
            }
    

    相关文章

      网友评论

          本文标题:Vue实现表单验证组件和弹框组件

          本文链接:https://www.haomeiwen.com/subject/ifpfpctx.html