携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情
1、el-table和el-form实现表头合并单元格和表格表单校验
日常需求可能会遇到表格嵌套表单,使表格中的数据进行校验
- 表头合并单元格:使用
el-table-column再包一层el-table-column,例如<el-table-column label="地址"><el-table-column prop="province" label="省份" width="120"></el-table-column><el-table-column prop="city" label="城市" width="120"></el-table-column></el-table-column> - 表格表单校验:使用
el-form包裹el-table
-
el-form属性:
-
-
:model="validateForm"在使用 validate、resetFields 方法的情况下,model 是必填的label-width设置为0,因为表格内部表单不需要label
-
-
el-table属性:
-
-
:data="validateForm.commodityTableData",validateForm的结构为validateForm: {commodityTableData: []},
-
-
el-form-item属性:
-
-
:prop="'commodityTableData.' + scope.$index +.${item.key}"找到对应表格中的key,用于校验:rules="{ required: true, message:${item.label}不能为空, trigger: 'blur' }"校验规则,使用表头label提示对应的报错信息
-
- 校验函数:
state.formTableRef.validate((valid: any) => { if ( valid) {...} })进行校验
完整代码:
- buttonList操作按钮按需求自定义设置,callback为点击后回调
- staticData按对应的数据格式进行设置
<el-form :model="validateForm" ref="formTableRef" label-width="0">
<el-table ref="tableRef" row-key="id" border :data="validateForm.commodityTableData" v-loading="tableLoading" stripe highlightCurrentRow :highlight-current-row="false">
<el-table-column show-ovexrflow-tooltip width="100px" label="操作" fixed="left">
<template v-slot="scope">
<template v-for="item in buttonList">
<span :key="item.key" :class="`action-btn btn ${item.key}`" v-if="item.disabledFunc?item.disabledFunc(scope.row,item):true"
@click="item.callback?item.callback(scope):()=>{}">{{item.label}}</span>
</template>
</template>
</el-table-column>
<el-table-column v-for="(itm) in commodityColumnList" :key="itm.label" :label="itm.label" align="center">
<el-table-column :show-overflow-tooltip="!item.type || item.type === 'text'" v-for="item in itm.list.filter((item) => item.isShow)" :key="item.key":prop="item.key" :label="item.label" :type="item.type" :min-width="item.width ? item.width : (item.label.length * 22 > 80 ? item.label.length * 22 : 80)">
<template v-if="item.type === 'link'" v-slot="scope">
<a :style="{ color: '#409EFF' }" class="action-btn" @click.stop="item.callback(scope.row,item)" >{{ `${scope.row[item.key] || item.initialValues}` }}</a>
</template>
<template v-else-if="item.type === 'inputNumber'" v-slot="scope">
<el-form-item :prop="'commodityTableData.' + scope.$index + `.${item.key}`" :rules="{ required: true, message: `${item.label}不能为空`, trigger: 'blur' }" >
<el-input-number v-model="scope.row[item.key]" :min="0" :max="scope.row['goodsNum']" :controls="false"></el-input-number>
</el-form-item>
</template>
<template v-else-if="item.type === 'date'" v-slot="scope">
<el-form-item :prop="'commodityTableData.' + scope.$index + `.${item.key}`" :rules="{ required: true, message: `${item.label}不能为空`, trigger: 'blur' }" >
<el-date-picker v-model="scope.row[item.key]" type="date"></el-date-picker>
</el-form-item>
</template>
<template v-else-if="item.type === 'select'" v-slot="scope">
<el-form-item :prop="'commodityTableData.' + scope.$index + `.${item.key}`" :rules="{ required: true, message: `${item.label}不能为空`, trigger: 'change' }" >
<el-select clearable v-model="scope.row[item.key]" filterable @change="(e) => {item?.changeCallBack && item?.changeCallBack(e, scope.$index)}">
<el-option v-for="item2 in staticData[item.key] || []" :key="item2.value" :label="item2.name" :value="item2.value"></el-option>
</el-select>
</el-form-item>
</template>
<template v-else-if="item.type === 'input'" v-slot="scope">
<el-form-item :prop="'commodityTableData.' + scope.$index + `.${item.key}`" :rules="{ required: true, message: `${item.label}不能为空`, trigger: 'blur' }" >
<el-input v-model="scope.row[item.key]" clearable ></el-input>
</el-form-item>
</template>
</el-table-column>
</el-table-column>
</el-table>
</el-form>
const state = reactive<ICompStateData>({
validateForm: {
commodityTableData: [],
},
commodityColumnList: [
{
label: "调出信息",
list: [
{ key: "billStatus", label: "订单状态", isShow: true },
{ key: "deliverStatus", label: "发货状态", isShow: true },
{ key: "orderUnit", label: "订单单位", isShow: true },
{ key: "unitName", label: "基本单位", isShow: true },
{ key: "goodsNum", label: "剩余数量", isShow: true },
]
},
{
label: "调入信息",
list: [
{ key: "reason", label: "原因", isShow: true, type: 'select', width: 160 },
{ key: "num", label: "数量", isShow: true, type: 'inputNumber', width: 160 },
{ key: "mode", label: "模式", isShow: true, type: 'select', width: 160, changeCallBack: (e: any, index: number) => {
}
},
{ key: "remark", label: "备注", isShow: true, type: 'input', width: 160 },
{ key: "date", label: "日期", isShow: true, type: 'date', width: 160 },
]
},
],
ruleForm: ref(null),
formTableRef: ref(null),
//静态数据
staticData: {billStatus: [value: 0, name: '初始化']}
})
效果:
2、日期选择el-date-picker当日及之前日期不可选
- disabledDate:设置禁用状态,参数为弹窗显示的对应日期,要求返回 Boolean
disabledDate: (time: any) => { return time.getTime() <= Date.now() } - el-date-picker:设置对应属性
<el-date-picker v-model="date" type="date" :disabled-date="disabledDate" ></el-date-picker>
效果: