一、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>