一、效果图如下
二、实现方法
以下方法可以判断当前行是否选中(核心实现代码)
javascript
// 判断是否是选中的数据
const isSeledted = computed(() => record => {
return state.selectedRowKeys.some(id => id === record.id);
});
在需要需要检验的字段的判断一下就好, 如果当前行勾选了, 就加上rules的校验, 否则就为rules = null
javascript
:rules="isSeledted(record) ? [{ required: true, message: '请输入用途', trigger: 'blur' }] : null"
html
<template #bodyCell="{ column, text, record, index }">
<template v-if="column.dataIndex == 'purpose'">
<div style="height: 44px" v-if="currentStep === 0">
<a-form-item
class="custom-form-item"
label=" "
:colon="false"
:name="[index, 'purpose']"
:rules="isSeledted(record) ? [{ required: true, message: '请输入用途', trigger: 'blur' }] : null">
<a-input style="width: 100%" v-model:value="record[column.dataIndex]"></a-input>
</a-form-item>
</div>
<span v-else>{{ text }}</span>
</template>
<template v-else-if="column.dataIndex == 'MBstate'">
<span>已分配</span>
</template>
</template>
三、完整代码
html
<template>
<div class="allot-warp">
<a-form ref="tableFormRef" :model="state.tableSource" :label-col="{ style: { width: '10px' } }" :wrapper-col="{ span: 0 }">
<a-table
:row-key="_ => _.id"
class="ant-table-striped"
bordered
:dataSource="tableSource"
:columns="resultTableColumns"
:pagination="Pagination"
:scroll="{ x: tableWidth }"
:row-selection="
currentStep == 0
? {
selectedRowKeys: selectedRowKeys,
onChange: handleSelectChange
}
: null
"
:row-class-name="(_record, index) => (index % 2 === 1 ? 'table-striped' : null)">
<template #headerCell="{ column }">
<template v-if="column.dataIndex === 'result'">
<div class="result-warp">
<span>配置结果</span>
<a-button type="link" @click="handleConfigResult">
<template #icon>
<SearchOutlined />
</template>
</a-button>
</div>
</template>
</template>
<template #title="{ column }">
<div v-if="currentStep == 1" style="display: flex; justify-content: space-between; align-items: center">
<span>!红色背景代表配置校验未通过,黄色背景代表配置校验需要二次确认,绿色背景代表配置校验通过</span>
<a-button type="primary" size="small" @click="handleExport">
导出
<template #icon>
<ArrowDownOutlined />
</template>
</a-button>
</div>
</template>
<template #bodyCell="{ column, text, record, index }">
<template v-if="column.dataIndex == 'purpose'">
<div style="height: 44px" v-if="currentStep === 0">
<a-form-item
class="custom-form-item"
label=" "
:colon="false"
:name="[index, 'purpose']"
:rules="isSeledted(record) ? [{ required: true, message: '请输入用途', trigger: 'blur' }] : null">
<a-input style="width: 100%" v-model:value="record[column.dataIndex]"></a-input>
</a-form-item>
</div>
<span v-else>{{ text }}</span>
</template>
<template v-else-if="column.dataIndex == 'MBstate'">
<span>已分配</span>
</template>
</template>
</a-table>
</a-form>
</div>
</template>
<script setup>
import { ArrowDownOutlined, SearchOutlined } from '@ant-design/icons-vue';
import { Modal } from 'ant-design-vue';
import { computed, h, reactive, ref, watch } from 'vue';
import VLANConfigDetail from '../components/VLANConfigDetail.vue';
const steps = [{ title: '分配选择' }, { title: '配置校验' }, { title: '分配入库' }];
let currentStep = ref(0);
const state = reactive({
orderInfo: {
orderId: ''
},
selectedRowKeys: []
});
let resultTableColumns = ref();
import useTable from './hooks/useTable.js';
const { tableSource, tableColumns, step2TableColumns, tableWidth, Pagination, getListFn, handleConfigResult, handleExport } = useTable();
const handleSelectChange = (selectedRowKeys, selectedRows) => {
state.selectedRowKeys = selectedRowKeys;
console.log('-------- selectedRowKeys --------', state.selectedRowKeys);
};
// 判断是否是选中的数据
const isSeledted = computed(() => record => {
return state.selectedRowKeys.some(id => id === record.id);
});
// 查询接口
getListFn();
const configDetailRef = ref(null);
// 查看VLAN配置详情
const handleDetail = () => {
configDetailRef.value.init('allot');
};
// 确认分配
const handleAllotSubmit = () => {
console.log('handleAllotSubmit');
Modal.confirm({
title: '分配选择提交',
content: '确认提交分配选择吗,确认提交即进行下一步配置校验',
okText: '确 认',
cancelText: '取 消',
centered: true,
onOk() {
currentStep.value = 1;
},
onCancel() {}
});
};
let step4Tip = row => {
return h('div', null, [
h('div', {}, [h('div', {}, '情景1:'), h('div', {}, `${row.tip}`)]),
h('div', {}, [h('div', {}, '情景1:'), h('div', {}, `${row.tip}`)]),
h('div', {}, [h('div', {}, '情景1:'), h('div', {}, `${row.tip}`)])
]);
};
// 确认配置检验
const handleAllot2Submit = () => {
Modal.confirm({
title: '预埋确认',
content: step4Tip({ tip: '经再次校验,xx平面目标VLAN值:xxx,xxx现网未配置,无法预埋!请进行实施配置' }),
okText: '确 认',
cancelText: '取 消',
centered: true,
onOk() {
currentStep.value = 2;
},
onCancel() {
console.log('Cancel');
}
});
};
// 返回上一步
const handleBack = () => {};
watch(
currentStep,
val => {
if (val === 1) {
resultTableColumns.value = step2TableColumns.value;
} else {
resultTableColumns.value = tableColumns.value;
}
},
{ immediate: true }
);
</script>
<style lang="less" scoped>
.allot-warp {
width: 100%;
height: 100%;
padding: 20px;
background-color: #f5f5f5;
.setps-warp {
width: 100%;
padding: 50px 40px;
background-color: #fff;
}
.content-warp {
margin-top: 15px;
padding: 40px 20px;
background-color: #fff;
.content-tip {
padding: 0 0 20px 0;
.tip-title {
font-size: 16px;
}
.tip-warp {
margin-top: 10px;
padding-left: 20px;
.tip-item {
margin-bottom: 10px;
font-size: 14px;
}
}
}
}
}
.order-info-warp {
padding: 20px 20px 0 20px;
background-color: #fff;
display: flex;
.order-title {
font-size: 18px;
font-weight: 600;
display: flex;
align-items: center;
margin-bottom: 20px;
}
.order-title::before {
content: '';
display: inline-block;
width: 5px;
height: 18px;
background-color: #1890ff;
margin-right: 10px;
}
.order-item-warp {
margin: 10px 0;
label {
display: inline-block;
width: 100px;
padding-left: 20px;
}
}
}
</style>