6.3Element UI 的表单

Element UI 的表单

  1. <el-form> : 表单的根容器,负责管理表单的整体状态(如布局、验证、提交)。
  2. <el-form-item> : 表单项的容器,负责包裹一个具体的表单控件,并管理其标签(label)、校验状态(错误信息、校验图标)和布局。
  3. 表单控件 : 实际的输入组件,如 <el-input><el-select><el-date-picker> 等。它们被放置在 <el-form-item> 内。
  4. v-model : Vue 的双向绑定指令,用于将表单控件的值与 Vue 实例的数据 (data) 进行绑定。
  5. modelrules : <el-form>model 属性绑定整个表单数据对象,rules 属性定义校验规则。
  6. prop : <el-form-item>prop 属性,必须对应 model 对象中的字段名,这是将表单项与校验规则关联起来的关键。

基本结构示例:

复制代码
<template>
  <el-form :model="form" :rules="rules" ref="ruleForm">
    <el-form-item label="活动名称" prop="name">
      <!-- 具体的表单控件 -->
      <el-input v-model="form.name"></el-input>
    </el-form-item>
    <el-form-item label="活动区域" prop="region">
      <el-select v-model="form.region" placeholder="请选择活动区域">
        <el-option label="区域一" value="shanghai"></el-option>
        <el-option label="区域二" value="beijing"></el-option>
      </el-select>
    </el-form-item>
    <el-form-item>
      <el-button type="primary" @click="submitForm('ruleForm')">立即创建</el-button>
      <el-button @click="resetForm('ruleForm')">重置</el-button>
    </el-form-item>
  </el-form>
</template>

<script>
export default {
  data() {
    return {
      form: {
        name: '',
        region: ''
      },
      rules: {
        name: [
          { required: true, message: '请输入活动名称', trigger: 'blur' }
        ],
        region: [
          { required: true, message: '请选择活动区域', trigger: 'change' }
        ]
      }
    };
  },
  methods: {
    submitForm(formName) {
      this.$refs[formName].validate((valid) => {
        if (valid) {
          alert('submit!');
        } else {
          console.log('error submit!!');
          return false;
        }
      });
    },
    resetForm(formName) {
      this.$refs[formName].resetFields();
    }
  }
}
</script>

<el-form-item>

表单项的容器,负责布局和校验展示。

  • prop: 必填(当使用校验时) 。必须等于 model 对象中的字段名 (如 name)。这是将此表单项与 rules 中的校验规则关联起来的桥梁。
  • Element UI 的表单系统设计精良,通过 <el-form><el-form-item> 和丰富的表单控件,配合 v-modelmodelrulesprop,能够高效地构建出功能完整、校验严谨的表单界面。

在 Element UI 的默认布局下,大多数表单控件在 <el-form-item> 内是默认沾满其父容器(即 <el-form-item> 的内容区域)的整行宽度的

1. 块级布局 (inline 属性为 false - 默认情况)

这是最常见的表单布局模式。

  • <el-form-item> : 每个表单项默认是块级元素,独占一行。
  • 内部的表单控件 (如 <el-input>, <el-select>, <el-date-picker> 等) : 在这种模式下,这些控件默认会撑满 <el-form-item> 内容区域 (el-form-item__content) 的整个宽度

示例:

复制代码
<el-form :model="form" label-width="100px">
  <!-- 这个输入框会沾满 label 之后的剩余空间 -->
  <el-form-item label="姓名">
    <el-input v-model="form.name"></el-input> <!-- 默认沾满整行(内容区域) -->
  </el-form-item>

  <!-- 这个选择器也会沾满整行(内容区域) -->
  <el-form-item label="城市">
    <el-select v-model="form.city" placeholder="请选择">
      <el-option label="北京" value="beijing"></el-option>
      <el-option label="上海" value="shanghai"></el-option>
    </el-select>
  </el-form-item>
</el-form>

在这个例子中,"姓名"和"城市"两个输入框/选择器都会各自占据其 <el-form-item> 内容区域的 100% 宽度。


2. 行内布局 (inline 属性为 true)

<el-form> 设置了 inline 属性时,布局行为完全不同。

  • <el-form-item> : 会变成行内块级元素 (inline-block),可以与其他表单项并排显示。
  • 内部的表单控件 : 它们的宽度不再自动沾满 。它们的宽度通常由其自身内容或内部逻辑决定(例如 <el-input> 会根据 size 有一个默认宽度,<el-button> 有自己的默认尺寸)。

示例:

复制代码
<el-form :inline="true" :model="form">
  <!-- 这两个表单项会并排显示 -->
  <el-form-item label="姓名">
    <el-input v-model="form.name"></el-input> <!-- 宽度由自身决定,不会沾满 -->
  </el-form-item>
  <el-form-item label="年龄">
    <el-input v-model.number="form.age" type="number"></el-input>
  </el-form-item>
  <el-form-item>
    <el-button type="primary">查询</el-button> <!-- 按钮有固定宽度 -->
  </el-form-item>
</el-form>

在这个例子中,"姓名"、"年龄"输入框和"查询"按钮会水平排列,它们的宽度是各自独立的,不会自动占满父容器。


如何控制控件宽度?

即使在默认的块级布局下,你也可以轻松地改变控件的宽度:

直接设置 width 样式:

复制代码
   <el-form-item label="短输入框">
     <el-input v-model="form.short" style="width: 200px;"></el-input>
   </el-form-item>

使用 <el-row><el-col> (推荐): 如上一个问题所述,这是最标准和灵活的方式。

复制代码
   <el-form-item label="组合">
     <el-row :gutter="10">
       <el-col :span="12">
         <el-input v-model="form.part1"></el-input>
       </el-col>
       <el-col :span="12">
         <el-input v-model="form.part2"></el-input>
       </el-col>
     </el-row>
   </el-form-item>

使用 CSS Flex 布局 (自定义样式)

通过给 <el-form-item> 或其内部容器添加自定义的 CSS 类,使用 Flexbox 进行布局。

复制代码
  <template>
    <el-form :model="form" label-width="100px">
      <!-- 使用自定义类名 -->
      <el-form-item label="自定义布局" class="flex-row">
        <div class="flex-container">
          <el-input v-model="form.input1" style="flex: 1; margin-right: 10px;"></el-input>
          <el-input v-model="form.input2" style="flex: 1; margin-right: 10px;"></el-input>
          <el-button type="primary">提交</el-button>
        </div>
      </el-form-item>
    </el-form>
  </template>

  <style scoped>
  /* 方法 3a: 使用 scoped 样式 */
  .flex-row >>> .el-form-item__content {
    /* 穿透 scoped,让 .el-form-item__content 使用 flex */
    display: flex;
    align-items: center; /* 垂直居中对齐 */
  }

  .flex-row >>> .el-form-item__content .el-input {
    margin-right: 10px; /* 控件间间距 */
  }

  .flex-row >>> .el-form-item__content .el-input:last-child {
    margin-right: 0;
  }

  /* 方法 3b: 更明确的容器 (推荐,避免穿透) */
  .flex-container {
    display: flex;
    align-items: center;
    width: 100%; /* 确保填满内容区域 */
  }

  .flex-container .el-input {
    flex: 1; /* 输入框伸缩填充空间 */
    margin-right: 10px;
  }

  .flex-container .el-input:last-child {
    margin-right: 0;
  }

  .flex-container .el-button {
    /* 按钮不伸缩 */
  }
  </style>
优点:
  1. 高度自定义: 可以实现非常灵活的布局。
  2. 现代布局: Flexbox 是现代 CSS 布局的标准。
  • 缺点
  1. 需要写 CSS: 增加了额外的样式代码
适用场景: 需要特殊布局,且栅格系统难以实现时。
>>> 穿透问题: 如果使用 scoped,需要使用 >>> (或 /deep/, ::v-deep) 穿透到 Element UI 的组件内部类(如 .el-form-item__content),这可能破坏样式封装,且在某些构建工具中需要配置。
维护性: 相比使用内置栅格,可能需要更多 CSS 调试。

总结

  • 在默认的块级布局 (inline=false) 下,<el-form-item> 内的表单控件(如 el-input, el-select)会默认沾满其内容区域的整行宽度。
  • 在行内布局 (inline=true) 下,表单项和内部控件都不会自动沾满,而是根据内容或自身尺寸显示。
  • 你可以通过 style="width: ..." 或使用 <el-row>/<el-col> 栅格系统来精确控制控件的宽度,覆盖默认的沾满行为。
相关推荐
本末倒置18314 分钟前
Svelte邪修的JSDoc,到底是个啥?
前端·javascript·面试
李明卫杭州20 分钟前
CSS中的background-clip详解
前端·javascript
荻酷社区34 分钟前
HTML+CSS+JavaScript实现的AES加密工具网页应用,包含完整的UI界面和加密/解密功能
javascript·css·html
彭于晏爱编程41 分钟前
密码的,YOU不能不知道的Next.jsSSR(服务端渲染)
前端·javascript·react.js
yvvvy1 小时前
前端性能优化全家桶:从重绘重排到面试连招,一篇搞懂
前端·javascript·面试
小蒜学长1 小时前
vue家教预约平台设计与实现(代码+数据库+LW)
java·数据库·vue.js·spring boot·后端
串串狗xk1 小时前
使用 webgl 写的新概念笔记应用《赛博城寨》,在三维开放世界里写笔记
javascript·webgl
页面仔Dony2 小时前
流式数据获取与展示
前端·javascript
前端进阶者3 小时前
electron-vite_20外部依赖包上线后如何更新
前端·javascript·electron
阿虎儿3 小时前
TypeScript 内置工具类型完全指南
前端·javascript·typescript