具体代码连接
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('错误');
// }
})
}
网友评论