美文网首页
Vue.js-ElementUI表单

Vue.js-ElementUI表单

作者: 书上得来终觉浅 | 来源:发表于2019-09-25 15:07 被阅读0次

1 表单el-form

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

1.1 表单的模型对象model

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

<el-form :model="dto">
  <el-form-item label="名字">
    <el-input v-model="dto.name"></el-input>
  </el-form-item>
</el-form>

<script>
    export default{
    data(){
      return {
        dto:{name:"张三"},
      }
    }
  }
</script>

上面的代码: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)的表单域,都会添加后缀。
<!-- 在表单元素上统一设置了表单域标签元素的位置和宽度 -->
<el-form label-position='left' label-width='100px' :model="dto">
    <el-form-item label="名称">
    <el-input v-model="dto.name"></el-input>
  </el-form-item>
  <!-- 单独设置该表单域的标签宽度,优先级高于el-form上设置的宽度 -->
  <el-form-item label="组名称" label-width='120px'>
    <el-input v-model="dto.name"></el-input>
  </el-form-item>
</el-form>

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

<el-form-item>
  <!--使用具名插槽设置label-->
  <template v-slot:lable>
    <img :src="logo" alt="" style="width:16px">
  </template>
  <el-input v-model="dto.name"></el-input>
</el-form-item>

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

1.3 表单域的布局

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

<div class="el-input">
  <input type="text" class="el-input__inner"/>
</div>

<!--
    el-input样式中width:100%
    el-input__inner样式中width:100%
-->

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

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

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

<template>
    <div id="app">
    <el-input class="width-200" />
  </div>
</template>
<style>
  .width-200{
    width:200px;
  }
</style>

渲染后的结构是

<head>
  <style type="text/css">
    /*不会生效*/
    .width-200 {
      width: 200px;
    }
  </style>
  <style type="text/css">
    /*element中的样式*/
  </style>
</head>
<body>
  <div class="width-200 el-input">
    <input type="text" class="el-input__inner"/>
  </div>
</body>

width-200(width:200px)和el-input(width:100%)中都有width属性,因为<div class="width-200 el-input">中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指定规则名。

<template>
  <div id="app">
    <!-- 
      使用model指定模型对象,使用rules指定规则对象
      模型对象就是规则要验证的数据对象
     -->
    <el-form ref="validateForm" :model="dto" :rules="rules" label-width="80px">
      <!-- 在表单域中使用prop属性指定规则对象中的规则名 -->
      <el-form-item label="名字" prop="name">
        <el-input v-model="dto.name"></el-input>
      </el-form-item>
      <el-form-item label="组名字" prop="groupName">
        <el-input v-model="dto.groupName" />
      </el-form-item>
    </el-form>
  </div>
</template>
<script>
export default {
  data() {
    return {
      dto: { name: "张三", groupName: "管理组" },
      //规则对象定义,键为对象名,建议与数据对象的键相同,
      //值为规则,可以是单条规则,也可以是集合
      rules: {
        // trigger是element中自定义的属性,见触发验证一节
        name: { required: true, message: "名称为必填项", trigger: "blur" },
        groupName: [
          //gorupName有多条规则,不同的规则验证不同的方面
          { required: true, message: "组名为必填", trigger: "blur" },
          { min: 3, max: 16, message: "组名长度在3-16之间", trigger: "blur" },
          { pattern: /^\w+$/, message: "不能包含特殊字符", trigger: "blur" }
        ]
      }
    };
  },
};
</script>

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选择器表示字段的输入类型,有文本、单选两种。当为文本时,可以填写文本的默认值(非必须),当为单选时,要填写单选的取值范围(必须)。

需求:

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

代码实现:

<template>
  <div id="app">
    <el-form ref="form" :model="dto" :rules="rules" label-width="80px">
      <el-form-item label="输入类型">
        <el-select v-model="dto.type">
          <el-option
            v-for="(item,index) in inputType"
            :key="'inputType'+index"
            :value="item.value"
            :label="item.label"
          ></el-option>
        </el-select>
      </el-form-item>
      <!-- 
        prop的值改变时,要重新渲染el-form-item元素,
        但是vue出于性能的考虑,会复用之前的el-form-item元素,
        添加key属性可以强制使用新的el-form-item元素
       -->
      <el-form-item :key="'key'+inputValueRule" label="字段值" :prop="inputValueRule">
        <el-input v-model="dto.inputValue"></el-input>
      </el-form-item>
    </el-form>
  </div>
</template>
<script>
const inputType = [{ value: 0, label: "文本" }, { value: 1, label: "单选" }];
const rules = {
  inputValue: [
    { required: true, message: "字段值为必填", trigger: "blur" },
    {
      //使用正则表达式做逗号验证
      pattern: /^([\u0391-\uFFE5\d\w,])*([\u0391-\uFFE5\d\w]+)$/g,
      message: "选项需要用','号隔开",
      trigger: "blur"
    }
  ]
};
export default {
  data() {
    return {
      inputType,
      rules,
      dto: {
        type: 0,
        inputValue: ""
      }
    };
  },
  computed:{
    inputValueRule(){
      //当输入类型类单选时,返回规则指定的规则名称
      return this.dto.type==1?"inputValue":"";
    }
  }
};
</script>

相关文章

  • Vue.js-ElementUI表单

    1 表单el-form 每个表单el-form由多个表单域el-form-item组成。默认情况,表单域是垂直分布...

  • bootstrap之form表单

    表单布局 垂直表单(默认) 内联表单 水平表单 垂直表单或基本表单(display:block;) 创建基本表单的...

  • 【读书笔记+思考】移动设备表单设计

    在移动界面中,常见的表单模式有:登录表单;注册表单;核对表单;计算表单;搜索表单;多步骤表单;长表单等 登录表单:...

  • bootstrap表单

    表单布局 垂直表单(默认) 内联表单 水平表单 垂直表单或基本表单 基本的表单结构是 Bootstrap 自带的,...

  • bootstrap 表单布局的三种方式

    三种 垂直表单(默认) 内联表单 水平表单 垂直表单 效果 内联表单 效果 水平表单 效果 参考:https://...

  • 表单相关总结

    表单?表单作用:收集用户信息。表单组成:表单域、表单控件、提示信息。 表单域常用属性 常用属性: name=...

  • 网页设计:HTML表单标签

    表单包含三个基本组成部分:表单标签、表单域、表单按钮。 1,表单标签 HTML 表单用于收集用户输入,表单使用 ...

  • 2019-04-09 表单(5)

    表单布局Bootstrap 提供了下列类型的表单布局: 垂直表单(默认) 内联表单 水平表单 1.垂直或基本表单 ...

  • 动态表单实现

    angular动态表单 地址: angular表单 vue动态表单 地址: vue表单

  • bootstrap表单

    垂直表单(默认) 内联表单 水平表单 垂直表单 也称基本表单基本的表单结构是 bootstrap 自带的创建基本表...

网友评论

      本文标题:Vue.js-ElementUI表单

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