el-table-column嵌套el-form-item不能进行校验问题解决

项目为vue3+elementPlus开发的项目

业务要求:table表格展示数据,其中有一行是ip地址可展示可修改,此处要求增加自定义校验规则

先看一下效果:

此处先描述一下,问题出在了哪里,我将el-table的data,使用一个ref数组存储,表格校验使用了一个对象存储,导致,校验的时候拿不到数据,代码如下

<template>
<el-form ref="ruleFormRef" :model="form" :rules="probeIpFormRules">
<el-table
     :data="tableData"
     empty-text="暂无数据"
      height="calc(100% - 40px)"
      :border="true"
      style="width: 100%"
      v-loading="loading"
      element-loading-background="rgba(255, 255, 255, 0.5)"
      >
          <el-table-column type="index" label="序号" width="60" />
          <el-table-column prop="portName" min-width="190" label="端口号" />
          <el-table-column prop="probeIp" min-width="160" label="探针IP">
            <template #default="{ row, $index }">
              <el-form-item :prop="`tableData[${$index}].probeIp`" :rules="probeIpFormRules.probeIp">
                <el-input class="probeIp-style" v-model.trim="row.probeIp" autocomplete="off" clearable />
              </el-form-item>
            </template>
          </el-table-column>
        </el-table>
        </el-form>
</template>
<script setup lang="ts">
 const  probeIpFormRules= {
    probeIp: [{ required: false, message: '请输入ip地址', trigger: 'change' }, { validator: checkIp }],
  }
const tableData=ref([])
</script>

以下是正确代码,就是将tableData和probeIpFormRules放到同一个对象里

<template>
  <el-dialog
    title="设置交换机端口"
    v-model="dialogVisible"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    draggable
    width="90%"
    @closed="handleClose"
  >
    <el-form ref="ruleFormRef" :model="form" :rules="form.probeIpFormRules">
      <div class="box-warp">
        <div class="hd-header">
          <span>交换机ip: {{ switchIp }}</span>
          <div class="hd-btn">
            <el-button type="primary" @click="handleSave(ruleFormRef)" :loading="btnLoading">保存</el-button>
            <el-button @click="handleClose">关闭</el-button>
          </div>
        </div>

        <el-table
          :data="form.tableData"
          empty-text="暂无数据"
          height="calc(100% - 40px)"
          :border="true"
          style="width: 100%"
          v-loading="loading"
          element-loading-background="rgba(255, 255, 255, 0.5)"
        >
          <el-table-column type="index" label="序号" width="60" />
          <el-table-column prop="portName" min-width="190" label="端口号" />
          <el-table-column prop="portDes" min-width="200" label="端口描述" />
          <el-table-column prop="portRunningStatus" min-width="90">
            <template #header>
              <el-tooltip :visible="tooltipVisible" placement="top">
                <template #content>
                  <span>端口状态改变后请等待1分钟刷新查看</span>
                </template>
                <div class="status-style" @mouseenter="tooltipVisible = true" @mouseleave="tooltipVisible = false">
                  <span>当前端口状态</span>
                  <el-icon><QuestionFilled /></el-icon>
                </div>
              </el-tooltip>
            </template>
            <template #default="{ row }">
              <el-tag :type="showStatus(row.portRunningStatus)">
                {{ filterStatus(row.portRunningStatus) }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column prop="nominalBandwidth" min-width="100" label="额定带宽(Mb)">
            <template #default="{ row }">
              <el-input-number
                v-model="row.nominalBandwidth"
                :controls="false"
                :step="1"
                :min="0"
                :max="9999"
                :precision="0"
                style="width: 100%"
              />
            </template>
          </el-table-column>
          <el-table-column prop="probeName" min-width="190" label="探针名称">
            <template #default="{ row }">
              <el-input v-model.trim="row.probeName" maxlength="30" autocomplete="off" />
            </template>
          </el-table-column>
          <el-table-column prop="probeIp" min-width="160" label="探针IP">
            <template #default="{ row, $index }">
              <el-form-item :prop="`tableData[${$index}].probeIp`" :rules="form.probeIpFormRules.probeIp">
                <el-input class="probeIp-style" v-model.trim="row.probeIp" autocomplete="off" clearable />
              </el-form-item>
            </template>
          </el-table-column>
          <el-table-column label="端口操作" fixed="right" width="140">
            <template #default="{ row }">
              <el-switch
                v-model="row.portChangeStatus"
                :active-value="1"
                :inactive-value="2"
                active-text="ON"
                inactive-text="OFF"
                inline-prompt
                style="--el-switch-on-color: #13ce66; --el-switch-off-color: #f56c6c"
                @change="changevisible"
              />
            </template>
          </el-table-column>
        </el-table>
      </div>
    </el-form>
  </el-dialog>
</template>
<script setup lang="ts">
import { getPortByIp, savePort } from '@/api/switchModule'
import { validIpC } from '@/utils/validate.js'
const tooltipVisible = ref(false)
const ruleFormRef = ref()
/**
 * 状态显示
 */
const changevisible = () => {
  tooltipVisible.value = true
  const timer = setTimeout(() => {
    tooltipVisible.value = false
    clearTimeout(timer)
  }, 1000)
}
//校验子网地址格式
const checkIp = (rule: any, value: any, callback: any) => {
  if (value?.trim().length === 0) {
    callback(new Error('请输入ip地址'))
  } else if (value && !validIpC(value?.trim())) {
    callback(new Error('请输入正确格式的ip地址'))
  } else {
    callback()
  }
}

const dialogVisible = ref(false)
/**
 * 关闭弹窗
 */
const handleClose = () => {
  dialogVisible.value = false
}
const portStatus: Record<string, { label: string; color: 'success' | 'danger' }> = {
  '1': {
    label: '开启',
    color: 'success',
  },
  '2': {
    label: '关闭',
    color: 'danger',
  },
}
const filterStatus = (status: number) => {
  return portStatus[String(status)].label
}
const showStatus = (status: number) => {
  return portStatus[String(status)].color
}

const switchIp = ref('')
const btnLoading = ref(false)
const form = ref({
  tableData: [],
  probeIpFormRules: {
    probeIp: [{ required: false, message: '请输入ip地址', trigger: 'change' }, { validator: checkIp }],
  },
})

const handleSave = async (formEl: any) => {
  if (!formEl) return
  formEl.validate(async (valid: any) => {
    if (!valid) return
    ElMessageBox.confirm('确定提交端口信息吗?', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning',
    }).then(async () => {
      btnLoading.value = true
      try {
        const params = {
          switchIp: switchIp.value,
          resSwitchPortEntities: form.value.tableData,
        }
        console.log('请求保存的参数是==》', params)
        const { code, data } = await savePort(params)
        console.log('保存的数值为=》', code, data)
        dialogVisible.value = false
      } catch (error) {
        console.log('保存失败==》', error)
      } finally {
        btnLoading.value = false
      }
    })
  })
}
/**
 * 查询数据
 * @param switchIp
 */
const queryList = async (switchIp: string) => {
  loading.value = true
  try {
    const { code, data } = await getPortByIp({ switchIp })
    if (code !== 200 || data.resSwitchPortEntities.length === 0) return
    form.value.tableData = data.resSwitchPortEntities
  } catch (error) {
    console.log('错误==》', error)
  } finally {
    loading.value = false
  }
}

const openDialog = (ip: string) => {
  switchIp.value = ip
  //通过ip请求数据
  queryList(ip)
  dialogVisible.value = true
}
defineExpose({
  openDialog,
})
// 搜索对象
const searchForm = reactive({
  pageNum: 1,
  pageSize: 100,
  total: 0,
})
// 表格数据
const loading: Ref<boolean> = ref(false)
</script>

<style lang="scss" scoped>
.box-warp {
  height: 70vh;
  :deep(.el-input__wrapper) {
    box-shadow: 0 0 0 0px;
  }
  .hd-header {
    display: flex;
    justify-content: space-between;
    // margin-top: -20px;
    margin-bottom: 20px;
  }
  .probeIp-style{
    margin-top: 18px ;
  }
  .status-style {
    display: flex;
    align-items: center;
    justify-content: center;
  }
}
</style>

最终样式如下

Ï

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值