Vue项目-Table添加Form表单校验

一、HTML

html 复制代码
<template>
  <div class="taskInfo">
    <el-form
      :model="generateParams"
      :rules="formRules"
      ref="formRef"
      class="taskInfoForm"
      label-width="100px">
      <ul class="taskInfoSearch">
        <li>
          <el-form-item label="类型" prop="type">
            <el-select
              v-model="generateParams.type"
              placeholder="请选择类型">
              <el-option :value="1" label="aaa"></el-option>
              <el-option :value="2" label="bbb"></el-option>
            </el-select>
          </el-form-item>
        </li>
        <li>
          <el-form-item label="开始" prop="start">
            <el-input
              v-model="generateParams.start"
              placeholder="请输入开始值"></el-input>
          </el-form-item>
        </li>
        <li>
          <el-form-item label="结束" prop="end">
            <el-input
              v-model="generateParams.end"
              placeholder="请输入结束值"></el-input>
          </el-form-item>
        </li>
        <li>
          <el-form-item label="开始时间" prop="startTime">
            <el-date-picker
              v-model="generateParams.startTime"
              type="datetime"
              placeholder="请选择开始时间"
              format="YYYY/MM/DD hh:mm:ss"
              value-format="YYYY-MM-DD h:m:s" />
          </el-form-item>
        </li>
        <li>
          <el-form-item label="结束时间" prop="endTime">
            <el-date-picker
              v-model="generateParams.endTime"
              type="datetime"
              placeholder="请选择结束时间"
              format="YYYY/MM/DD hh:mm:ss"
              value-format="YYYY-MM-DD h:m:s" />
          </el-form-item>
        </li>
      </ul>

      <div class="taskInfoAddBtn">
        <el-button type="primary" @click="addRowData">新增表格数据</el-button>
      </div>

      <div class="taskInfoTab">
        <el-table
          :data="generateParams.studentInfo"
          :cell-class-name="cellClassName"
          :row-class-name="rowClassName"
          @cell-click="cellClick">
          <el-table-column label="姓名">
            <template #default="{ row, column }">
              <el-form-item
                :prop="'studentInfo.' + row.index + '.name'"
                :rules="formRules.name"
                v-if="row.index == rowIndex && column.index == columnIndex">
                <el-input
                  v-model.number="row.name"
                  type="number"
                  @blur="hideInput"
                  v-focus></el-input>
              </el-form-item>
              <span v-else>{{ row.name }}</span>
            </template>
          </el-table-column>
          <el-table-column label="年龄">
            <template #default="{ row, column }">
              <el-form-item
                :prop="'studentInfo.' + row.index + '.age'"
                :rules="formRules.age"
                v-if="row.index == rowIndex && column.index == columnIndex">
                <el-input
                  v-model.number="row.age"
                  type="number"
                  @blur="hideInput"
                  v-focus></el-input>
              </el-form-item>

              <span v-else>{{ row.age }}</span>
            </template>
          </el-table-column>
          <el-table-column label="性别">
            <template #default="{ row, column }">
              <el-form-item
                :prop="'studentInfo.' + row.index + '.sex'"
                :rules="formRules.sex"
                v-if="row.index == rowIndex && column.index == columnIndex">
                <el-input
                  v-model.number="row.sex"
                  type="number"
                  @blur="hideInput"
                  v-focus></el-input>
              </el-form-item>

              <span v-else>{{ row.sex }}</span>
            </template>
          </el-table-column>
          <el-table-column label="操作" width="100">
            <template #default="{ row }">
              <el-button type="danger" link @click="delRowData(row)"
                >删除</el-button
              >
            </template>
          </el-table-column>
        </el-table>
      </div>
    </el-form>

    <div class="generate">
      <el-button type="primary" @click="generate(formRef)"
        >任务信息生成</el-button
      >
    </div>

    <!-- 任务信息生成信息模态框 -->
    <TaskInfoModel ref="TaskInfoModelRef"></TaskInfoModel>
  </div>
</template>

二、JS

javascript 复制代码
<script setup>
// -------------------<<模块引入>>-------------------
import { ref, reactive, onMounted, nextTick } from "vue";
import { ElMessage } from "element-plus";
// -------------------<<变量声明>>-------------------
// 生成参数
const generateParams = reactive({
  type: 1, // 类型
  start: 1000000000, // 开始
  end: 2000000000, // 结束
  startTime: "2024-08-05 15:33:55", // 开始时间
  endTime: "2024-08-15 15:33:55", // 结束时间
  studentInfo: [
    // 任务区域
    {
      name: 123.1122331, // 姓名
      age: 80.12345621, // 年龄
      sex: 1200.1, // 性别
    },
    {
      name: 114.1122331, // 姓名
      age: 80.12345621, // 年龄
      sex: 1200.1, // 性别
    },
    {
      name: 114.1122331, // 姓名
      age: 80.12345621, // 年龄
      sex: 1200.1, // 性别
    },
  ],
});
// form表单规则
const formRules = reactive({
  type: [{ required: true, message: "请选择类型", trigger: "change" }],
  start: [{ required: true, message: "请输入开始", trigger: "blur" }],
  end: [{ required: true, message: "请输入结束", trigger: "blur" }],
  startTime: [{ required: true, message: "请选择开始时间", trigger: "change" }],
  endTime: [{ required: true, message: "请选择结束时间", trigger: "change" }],
  name: [{ required: true, message: "请输入姓名", trigger: "blur" }],
  age: [{ required: true, message: "请输入年龄", trigger: "blur" }],
  sex: [{ required: true, message: "请输入性别", trigger: "blur" }],
});
// 获取form表单ref
const formRef = ref();
// 行列index
const rowIndex = ref(null);
const columnIndex = ref(null);
// 是否允许编辑
const isEdit = ref(true);

// -------------------<<函数定义>>-------------------
// 生成
const generate = (formEl) => {
  if (!formEl) return;
  formEl.validate((valid) => {
    if (valid) {
      console.log(generateParams);
      TaskInfoModelRef.value.openWin();
    } else {
      console.log("error submit!");

      //当验证失败跳转到空白的所在区域
      nextTick(() => {
        let isError = document.getElementsByClassName("is-error");
        isError[0].scrollIntoView({
          // 滚动到指定节点
          // 值有start,center,end,nearest
          block: "center",
          // 值有auto、instant,smooth,缓动动画
          behavior: "smooth",
        });
      });

      return false;
    }
  });
};
// 表格单元格className回调方法
const cellClassName = ({ column, columnIndex }) => {
  column.index = columnIndex;
};
// 表格行className回调方法
const rowClassName = ({ row, rowIndex }) => {
  row.index = rowIndex;
};
// 表格单元格点击事件
const cellClick = (row, column) => {
  if (isEdit.value) {
    rowIndex.value = row.index;
    columnIndex.value = column.index;
  }
};
// input框失去焦点事件
const hideInput = (e) => {
  if (e.target.value) {
    rowIndex.value = null;
    columnIndex.value = null;
    isEdit.value = true;
  } else {
    isEdit.value = false;
  }
};
// 新增数据
const addRowData = () => {
  generateParams.studentInfo.push({
    name: "",
    age: "",
    sex: "",
  });
};
// 删除本行数据
const delRowData = (row) => {
  if (generateParams.studentInfo.length > 1) {
    generateParams.studentInfo.splice(row.index, 1);
  } else {
    ElMessage.warning("最少保留1条数据");
  }
};
// -------------------<<函数执行>>-------------------
onMounted(() => {});
</script>

三、CSS

css 复制代码
<style lang="less" scoped>
.taskInfo {
  width: 100%;
  height: 100%;

  :deep(.taskInfoForm) {
    width: 100%;
    height: calc(100% - 80px);

    .taskInfoSearch {
      width: 100%;
      height: 120px;
      display: flex;
      align-items: center;
      flex-wrap: wrap;

      li {
        width: 25%;
        height: 50%;

        .el-form-item__label {
          color: #fff;
        }

        .el-form-item {
          width: 100%;
          height: 100%;
          margin-bottom: 0px;
          display: flex;
          align-items: center;

          .el-date-editor.el-input,
          .el-input,
          .el-select {
            width: 100% !important;
          }
        }
      }
    }

    .taskInfoAddBtn {
      width: 100%;
      height: 50px;
      display: flex;
      align-items: center;
      justify-content: flex-end;
    }

    .taskInfoTab {
      width: 100%;
      height: calc(100% - 170px);
      position: relative;

      .el-table {
        width: 100%;
        height: 100%;
        background: transparent !important;
        position: absolute;

        .el-form-item {
          width: 100%;
          margin-bottom: 0px;

          .el-form-item__content {
            margin-left: 0px !important;
            display: flex;
            align-items: center;
            justify-content: center;

            .el-input,
            .el-select {
              width: 80% !important;
            }
          }
        }

        td,
        th {
          text-align: center;
        }
      }
    }
  }

  .generate {
    width: 100%;
    height: 80px;
    display: flex;
    align-items: center;
    justify-content: center;
  }
}
</style>
相关推荐
程序员凡尘21 分钟前
完美解决 Array 方法 (map/filter/reduce) 不按预期工作 的正确解决方法,亲测有效!!!
前端·javascript·vue.js
北岛寒沫5 小时前
JavaScript(JS)学习笔记 1(简单介绍 注释和输入输出语句 变量 数据类型 运算符 流程控制 数组)
javascript·笔记·学习
everyStudy5 小时前
JavaScript如何判断输入的是空格
开发语言·javascript·ecmascript
无心使然云中漫步6 小时前
GIS OGC之WMTS地图服务,通过Capabilities XML描述文档,获取matrixIds,origin,计算resolutions
前端·javascript
Bug缔造者6 小时前
Element-ui el-table 全局表格排序
前端·javascript·vue.js
xnian_7 小时前
解决ruoyi-vue-pro-master框架引入报错,启动报错问题
前端·javascript·vue.js
罗政7 小时前
[附源码]超简洁个人博客网站搭建+SpringBoot+Vue前后端分离
vue.js·spring boot·后端
麒麟而非淇淋8 小时前
AJAX 入门 day1
前端·javascript·ajax
2401_858120538 小时前
深入理解MATLAB中的事件处理机制
前端·javascript·matlab
阿树梢8 小时前
【Vue】VueRouter路由
前端·javascript·vue.js