vue3+antd-vue@4 a-form 嵌套a-table 实现行内 勾选才进行检验

13 篇文章 1 订阅
7 篇文章 1 订阅

一、效果图如下

二、实现方法

以下方法可以判断当前行是否选中(核心实现代码)

// 判断是否是选中的数据
const isSeledted = computed(() => record => {
  return state.selectedRowKeys.some(id => id === record.id);
});

在需要需要检验的字段的判断一下就好, 如果当前行勾选了, 就加上rules的校验, 否则就为rules = null

:rules="isSeledted(record) ? [{ required: true, message: '请输入用途', trigger: 'blur' }] : null"
<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>

三、完整代码

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

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

snows_l

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值