vue+elementui模板,vue elementui模板
本文主要介绍了Vue模拟元素UI的相关信息。通过示例代码进行了非常详细的介绍,对于大家的学习或者工作都有一定的参考价值。下面让我们跟随边肖一起学习。
实现要求
表单模拟元素UI分为四层:索引组件、表单组件、表单项组件、输入和复选框组件。具体分工如下:
索引组件:
实现:分别引入Form组件、FormItem组件和Input组件实现组装;
表单组件:
实现:预留槽、管理数据模型、自定义验证规则、全局验证方法验证;
表单项表单项组件:
实现:槽位预留、标签显示、数据校验、校验结果显示;
和输入框组件:
实现:绑定数据模型v-model,通知FormItem组件进行验证;
Input 组件
具体实现如下:
1.要实现v-model,自定义组件必须实现:value和@input。
2.当输入框中的数据发生变化时,通知父组件进行验证。
3.当输入组件绑定的类型是password时,在组件内部使用v-bind=$attrs 来获取除props之外的内容。
4.将inheritAttrs设置为false,以避免顶级容器继承属性。
组件实现:
模板
差异
input:value= value @ input= on input v-bind= $ attrs /
/div
/模板
脚本
导出默认值{
InheritAttrs: false,//避免顶级容器继承属性
道具:{
值:{
类型:字符串,
默认值:“”
}
},
data() {
return { };
},
方法:{
onInput(e)
//通知父组件值的变化。
这个。$emit(input ,e . target . value);
//通知FormItem进行验证
//这种编写方法并不健壮,因为Input组件和FormItem组件可能是分代的。
这个。$parent。$ emit( validate );
}
}
};
/脚本
样式范围/样式
注意:这个。代码中使用$parent来调度事件。这种书写方式并不健壮,当Input组件和FormItem组件相互分离时会出现问题。有关具体的解决方案,请参见文章末尾的代码优化部分。
CheckBox 组件
1.checkBox的双向数据绑定的自定义实现,类似于input,必须实现:checked和@change。
复选框组件实现:
模板
部分
输入类型= checkbox :checked= checked @ change= onChange /
/部分
/模板
脚本
导出默认值{
道具:{
已检查:{
类型:布尔型,
默认值:false
}
},
型号:{
道具:“已检查”,
事件:“更改”
},
方法:{
onChange(e) {
这个。$emit(change ,e . target . checked);
这个。$parent。$ emit( validate );
}
}
};
/脚本
样式范围的lang=less/style
FormItem 组件
具体实现如下:
1.为输入组件或复选框组件保留插槽。
2.如果用户在组件上设置了label属性,则应该显示label标签。
3.监控验证事件并执行验证(使用异步验证器插件进行验证)。
4.如果不满足验证规则,则需要显示验证结果。
在发展过程中,我们需要思考几个问题:
1.如何在组件中获取要验证的数据和验证规则?
2.表单中会有多个菜单项,如用户名、密码、邮箱等。那么FormItem组件如何知道它现在正在检查哪个菜单呢?
FormItem组件实现:
模板
div class=formItem-wrapper
div class=内容
label v-if= label :style= { width:label width } { { label } }:/label
插槽/插槽
/div
p v-if= error message class= error style { error message } }/p
/div
/模板
脚本
从“async-validator”导入架构;
导出默认值{
注入:[formModel],
道具:{
标签:{
类型:字符串,
默认值:“”
},
道具:绳子
},
data() {
返回{
错误消息:“”,
label width:this . formmodel . label width
};
},
已安装(){
//侦听验证事件并执行验证。
这个。$on(validate ,()={
this . validate();
});
},
方法:{
验证(){
//执行组件的验证
//1.检索数据
const values=this . form model . model[this . prop];
//2.获取验证规则。
const rules=this . form model . rules[this . prop];
//3.执行验证。
const schema=新模式({
[this.prop]:规则
});
//参数1是数值,餐数2是check error对象的数组。
//validate返回PromiseBoolean
返回schema . validate({[this . prop]:values },errors={
如果(错误){
this.errorMessage=errors[0]。消息;
}否则{
this . error message=“”;
}
});
}
}
};
/脚本
样式范围语言=less
@ label width:90px;for item-wrapper {
填充-底部:10px
}。内容{
显示器:flex
}。错误样式{
字体大小:12px
颜色:红色;
边距:0;
左填充:@ labelWidth
}
/风格
先回答上面提出的两个问题。这里会涉及到组件之间的价值传递。请参考之前的文章《组件传值、通讯》:
首先,表单的数据和校验规则在索引组件中定义,并挂载到表单组件上。表单的验证项出现在FormItem组件中。首先通过form组件中的props接收传输的数据,然后通过props/inject的方式传输给FormItem组件中的后代组件。
我们在日常生活中使用ElementUI检查表单时,会发现每个需要检查的表单上都设置了一个prop属性,属性值与绑定的数据一致。这里的目的是在FormItem组件中进行校验时,获取相关的校验规则和数据对象。
在FormItem组件中,通过使用inject获取注入的表单实例,结合prop属性,可以获取表单数据和校验规则。
//1.检索数据
const values=this . form model . model[this . prop];
//2.获取验证规则。
const rules=this . form model . rules[this . prop];
使用async-validator插件实例化一个用于执行验证的schema对象。schema.validate需要传递两个参数。参数1是一个键值对对象,由当前要验证的字段和相应的规则组成。参数2是回调函数,用来获取错误信息(是数组)。validate方法返回PromiseBoolean。
注意:在这个组件的validate方法中,使用return的最后一个目的是在表单组件中执行全局验证。
Form 组件
具体实现如下:
1.为FormItem组件预留插槽。
2.将表单实例传递给后代,比如FormItem用来获得验证的数据和规则。
3.执行全局验证。
表单组件的实现:
模板
差异
插槽/插槽
/div
/模板
脚本
导出默认值{
提供(){
返回{
FormModel:这//将表单实例传递给后代,比如FormItem用来获得检查的数据和规则。
};
},
道具:{
型号:{
类型:对象,
必填:真
},
规则:{
类型:对象
},
labelWidth:字符串
},
data() {
return { };
},
方法:{
验证(cb) {
//执行全局验证
//映射结果是几个有希望的数组
常量任务=this。$ children . filter(item=item . prop)。map(item=item . validate());
//所有任务都必须验证成功才能被验证。
Promise.all(任务)。然后(()={
cb(真);
})。catch(()={
cb(假);
});
}
}
};
/脚本
样式范围/样式
我们在表单组件中使用provide来注入当前的组件对象,方便后人获取数据/方法。
在进行全局验证时,先用filter过滤掉不需要验证的组件(我们在FormItem组件上设置了prop属性,只要有这个属性就需要验证),然后在组件中执行validate方法(如果FormItem组件中没有使用返回数据,最后得到的结果都是未定义的),返回若干个Promise数组。
简单介绍一下Promise.all()方法:
Promise.all()方法接收一个承诺的可迭代的类型(注:数组、映射、集合都属于ES6的可迭代的类型)的输入,并且只返回一个承诺实例,那个输入的所有承诺的分解回调的结果是一个数组。这个承诺的分解回调执行是在所有输入的承诺的分解回调都结束,或者输入的可迭代的里没有承诺了的时候。它的拒绝回调执行是,只要任何一个输入的承诺的拒绝回调执行或者输入不合法的承诺就会立即抛出错误,并且拒绝的是第一个抛出的错误信息。
index 组件
定义模型数据、校验规则等等,分别引入形式组件、FormItem组件、输入组件,实现组装。
指数组件实现:
模板
差异
form:model= form model :rules= rules ref= loginForm label-width= 90px
表单项标签=用户名prop=用户名
输入v-model=表单模型。用户名/输入
/FormItem
表单项标签=密码prop=密码
输入类型= password v-model= form模型。密码/输入
/FormItem
表单项标签=记住密码记住
复选框v-model=表单模型。记住/复选框
/FormItem
表单项
button @click=onLogin 登录/按钮
/FormItem
/表单
/div
/模板
脚本
从" @/组件/表单/输入"导入输入;
从"@/组件/表单/复选框"导入复选框
从" @/组件/表单/表单项目"导入表单项目;
从" @/组件/表单/表单"导入表单;
导出默认值{
data() {
const validateName=(规则,值,回调)={
如果(!值){
回调(新错误(用户名不能为空));
} else if(值!==admin) {
回调(新错误(用户名错误-admin ));
}否则{
回调();
}
};
const validatePass=(规则,值,回调)={
如果(!值){
回调(假);
}否则{
回调();
}
};
返回{
表单模型:{
用户名: ,
密码: ,
记住:假的
},
规则:{
用户名:[{ required: true,validator: validateName }],
密码:[{必填:真,消息: 密码必填 }],
请记住:[{ required: true,message:记住密码必选,验证器:validatePass }]
}
};
},
方法:{
onLogin() {
这个参考文献。loginform。验证(是否有效={
if (isValid) {
警报(登录成功);
}否则{
警报(登录失败);
}
});
}
},
组件:{
输入,
复选框,
对于一个项目,
形式
}
};
/脚本
样式范围/样式
当我们点击登录按钮时,会执行全局校验方法,我们可以使用这个. refs.xxx获取数字正射影像图元素和组件实例。
在上面我们还留了一个小尾巴~,就是在投入组件中通知父组件执行校验,目前使用的是这个父母。$emit(),这样写有一个弊端,就是当投入组件和表单项组件之后隔代的时候,再使用这个父母获取不到表单项组件。
我们可以封装一个派遣方法,主要实现向上循环查找父元素并且派发事件,代码实现如下:
分派(事件名称,数据){
让父母=这个父母
//查找父元素
while (parent) {
//父元素用$emit触发
父母. emit(eventName,data);
//递归查找父元素
父母=父母父母
}
}
该方法可以借用混入类引入使用:mixins/emmiters.js
导出默认值{
方法:{
分派(事件名称,数据){
让父母=这个父母
//查找父元素
while (parent) {
//父元素用$emit触发
父母. emit(eventName,data);
//递归查找父元素
父母=父母父母
}
}
}
};
修改投入组件:
模板
差异
input:value= value @ input= on input v-bind= $ attrs /
/div
/模板
脚本
从" @/mixins/emmiter "导入em斜接;
导出默认值{
inheritAttrs: false,//避免顶层容器继承属性
mixins: [emmiter],
道具:{
值:{
类型:字符串,
默认值:""
}
},
data() {
return { };
},
方法:{
输入输出
//通知父组件数值发生变化
这个emit(input ,e . target。值);
//通知表单项执行校验
//这种写法不健壮,因为投入组件和表单项组件之间可能会隔代
//这个父母。$ emit( validate );
this . dispatch( validate );//使用mixin中emmiter的调度来解决跨级问题。
}
}
};
/脚本
样式范围/样式
总结
关于Vue模仿ElementUI形态的这篇文章到此为止。更多关于Vue模仿ElementUI表单的信息,请搜索我们之前的文章或者继续浏览下面的相关文章。希望你以后能支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。