美文网首页
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('错误');
                // }
            })
        }

相关文章