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> 栅格系统来精确控制控件的宽度,覆盖默认的沾满行为。
相关推荐
木心操作14 小时前
nodejs动态创建sql server表
前端·javascript·sql
一个很帅的帅哥14 小时前
Vue中的data为什么是函数?
前端·javascript·vue.js·data
南屿im15 小时前
用 Node.js 开发命令行工具:打造你的高效 CLI
前端·javascript
小刘鸭地下城15 小时前
深入解析 Vue 的异步 DOM 更新机制:nextTick 的正确使用指南
vue.js
一个很帅的帅哥17 小时前
Vue keep-alive
前端·javascript·vue.js·keep-alive
lbh17 小时前
Chrome DevTools 详解(一):Elements 面板
前端·javascript·浏览器
明里人17 小时前
React 状态库:Zustand 和 Jotai 怎么选?
前端·javascript·react.js
儒雅的烤地瓜18 小时前
JS | 如何把一个伪数组转换成一个真正的数组?
javascript·from方法·数组转换·扩展运算符·slice方法·push方法
β添砖java19 小时前
交互动效设计
前端·javascript·交互
一条有腹肌的咸鱼19 小时前
vue3+vite+element-plus封装npm插件遇到的问题,求大神搭救
vue.js