Vue.js-ElementUI表单

1 表单el-form

每个表单el-form由多个表单域el-form-item组成。默认情况,表单域是垂直分布的,可以设置el-forminline=‘true’属性,使表单水平分布,当多个表单域el-form在一行显示不完时,会自动换行。

1.1 表单的模型对象model

el-form使用model属性来描述表单的数据模型对象,在指定数据对象后,其下的form-item能够使用该数据对象,比如引用数据对象的值,或数据验证等。


  
    
  



上面的代码:model="dto"指定了表单的模型对象,在el-form-item表单域中对模型对象的值做了双向绑定,需要注意的是表单域中v-model='dto.name'即使没有模型对象,也是能够正常运行的。但是,表单的模型对象在表单调用其验证方法validate(见验证规则一节)时是必须的。

1.2 表单域的标签

每个表单域都有一个标签(不是必选),用el-form-item的label属性指定,表单域的标签有位置和宽度两个属性。

  • label-position 表示标签的对齐方式,它有right(默认)|left|top三个取值,该属性是加在el-form元素上的,即只能对其下所有表单域进行统一的设置。
  • label-width 表示标签的宽度,只有当label-position为right或left时有效,label-width的值需要带单位,比如label-width='120px'。label-width可以加载el-form元素上,表示对其下的所有表单域的标签进行统一的设置,也可以加载el-form-item元素上,表示对单个表单域标签设置,el-form-item的优先级高于el-form的优先级。
  • label-suffix 标签的后缀,该属性在el-form标签中设置。也就是说,如果设置了该项,其下的所有设置了标签(label)的表单域,都会添加后缀。


    
    
  
  
  
    
  

表单域的label属性是字符串类型的,如果要用其他类型(如图片)或复杂的标签样式,显然label是不能满足的,element为我们提供标签具名插槽,具名插槽的名称为label。


  
  
  

具名插槽的优先级高于label属性,同时,使用具名插槽后label-suffix属性设置的标签后缀也会失效。

1.3 表单域的布局

element对其定义的表单元素做了默认的样式,比如:e-input默认是width:100%,element会在input元素的外面包裹一层div,其渲染后的样子如下:

如上面的分析,如果要修改input的宽度,我们有以下几种方法:

  1. 为表单元素el-input添加一个类,设置其width
  2. 复写生成的div标签的el-input样式,设置其width
  3. 表单元素el-input外面设置一个外壳,为这个外壳设置width

我们为el-input组件添加的任何自定义样式,最后都会加在外层的div标签上,而webpack渲染出的最终页面,是先加载我们自定义的样式,后加载element的默认样式。所以,如果我们在自定义的样式中设置了宽度,会被默认样式覆盖掉,也就是说,我们在自定义样式中设置width值是不起作用的,如下:



渲染后的结构是


  
  


  

width-200(width:200px)和el-input(width:100%)中都有width属性,因为

中el-input在width-200的后面,所以,width-200中的宽度被覆盖。

我们可以利用css选择器优先级高低排列来处理这个问题,简单的说,我们将自定义的样式的权重设高,来解决无效的问题。选择器的权重用4个部分表示(0,0,0,0),分别表示(行内样式,ID选择器,类/属性/伪类,元素/伪元素),他们的优先级从右到左依次升高,同一个级别的的选择器有几个,该部分的数字就是几,比如:

/* demo1 权重(0,0,2,1)*/
.class-a .class-b div{
  color:red;
}
/* demo2 权重(0,0,1,3) */
.class-a div ul li{
  color:blue;
}

上面的例子中,demo1的优先级高于demo2,因为在类这个级别demo1高于demo2,所以不管在元素级别demo2的值怎么高,优先级也是比不过demo1。注意:

  • 权重表示方法没有进位的说法
  • !important是最高级别,它高于所有的权重

对于el-input我们可以在外面加一层id选择器,如#app .width-200{width:200px},这样width-200的优先级就高于el-input的优先级。

第2个解决方案中,在样式引入时(html的head标签中),复写的el-input样式会在element的el-input的样式之前,所以,element的el-input的样式会层叠掉自定义的el-input的样式。可以在自定义的el-input样式的宽度上使用!important,强制使用自定义样式的宽度,不推荐这种方式。

第3中方案比较好理解,在element中,可以使用栅格布局的方式来处理表单元素的位置。

2 表单验证

表单验证的对象是el-form中model属性指定的数据对象。

21 验证规则

element的验证规则使用async-validator,规则的部分属性如下:

属性名 说明
type 待验证对象的数据类型,取值范围:string(默认)|number|boolean|method|regexp|integer|float|array|object|enum|date|url|hex|email
required 是否为必须
pattern 正则表达式
min 最小值,string和array类型对比其length属性,number类型对比起本身的值
max 最大值,参照值与min相似
len 长度,参照值与min相似,但是他是进准的表达,比如验证一个array对象的len是3,那么,这个array的长度就必须为3才能满足条件,如果是number类型,表示这个值必须与len中的值一样
enum 当type:enum时,enum选项才有意义,它后接数组集合,验证数据是否在此集合中
fields 深度验证,当验证的type为object,可以验证其内部数据
message 错误消息,类型为字符串或函数
validator 自定验证函数,函数的参数为(rule,value,callback)

在element中,将规则封装到一个规则对象中,规则对象的键(规则名)要与模型对象的键一致。键的值就是具体的规则,它可以是一个对象包含规则的属性和值,也可以是一个数组对象包含多条规则。

规则对象与模型对象一样,由表单元素el-form引用,使用rules属性指定(模型对象由model属性指定)。有了对规则对象的引用,还需要在具体的表单域中指定使用那一条规则,在el-form-item表单域中使用prop指定规则名。



2.2 触发验证

element在验证规则中加入了自动触发条件trggier属性,目前它的取值为blurchange(默认)两项,表示当表单元素失去焦点,或内容改变时触发该项验证。注意,它们也可以组合使用,如:trigger:['blur','change']

我们也可以通过el-form的实例方法validate手动触发整个表单的验证,或者使用实例方法validateField指定部分字段做验证。这里提到了实例方法,也就是说我们要得到el-form的实例,一般使用vue的ref属性定义这个对象的引用名。

validateForm() {
  //通过refs获取表单的引用
  let { form } = this.$refs;
  //调用表单的实例方法validate做全部验证
  //该方法的参数为一个回调函数
  //回调函数有两个可选参数,一个表示是否验证通过,第二个是未通过的字段集合
  form.validate((result,errorFields)=>{
    console.log(result);
    console.log(errObject);
  })
},
validateFields(){
  //通过refs获取表单的引用
  let { form } = this.$refs;
  //调用表单的实例方法validateField做指定字段的验证
  //该方法的有两个参数,第一个为要验证的字段,如果是当用string,多个用array类型
  //第二个参数为回调函数,该函数只有一个string类型的参数,表示错误信息
  form.validateField(['name','groupName'],error=>{
    console.log(error);
  })
}

注意:使用validateField方法验证多个字段时,每验证一次,都会调用回调函数一次,通过验证的字段会error=='',没通过验证的字段,返回对应规则的message错误消息字段。

3 案例

有时候需要对字段做动态的验证,可以为表单域的prop动态绑定规则。比如:有一个select选择器表示字段的输入类型,有文本、单选两种。当为文本时,可以填写文本的默认值(非必须),当为单选时,要填写单选的取值范围(必须)。

需求:

字段类型:
    文本:填写默认值,非必须
    单选:填写选项,多个选项使用','分隔

代码实现:



你可能感兴趣的:(Vue.js-ElementUI表单)