Skip to content
 

实现合并行列并循环的 table 表格

更新: 9/4/2025字数: 0 字 时长: 0 分钟

1,效果图如下:

2.template 代码如下:

html
<table border="1">
  <thead>
    <tr>
      <th colspan="3">运动处方</th>
    </tr>
  </thead>

  <tr class="title">
    <th>类别</th>
    <th>子别</th>
    <th>信息</th>
  </tr>
  <!-- 个人基本信息 -->
  <tr>
    <td rowspan="4">个人基本信息</td>
  </tr>
  <tr>
    <td>姓名</td>
    <td>xxx</td>
  </tr>
  <tr>
    <td>性别</td>
    <td>{{ prescriptionData.sex }}</td>
  </tr>
  <tr>
    <td>年龄</td>
    <td>{{ prescriptionData.age }}岁</td>
  </tr>
  <!-- 病症信息 -->
  <tr>
    <td rowspan="4">病症信息</td>
  </tr>
  <tr>
    <td>疾病名称</td>
    <td>{{ prescriptionData.disease }}</td>
  </tr>
  <tr>
    <td>疾病等级</td>
    <td>{{ prescriptionData.diseaseLevel }}</td>
  </tr>
  <tr>
    <td>并发症</td>
    <td>{{ prescriptionData.complication }}</td>
  </tr>

  <tr>
    <td>主诉</td>
    <td></td>
    <td>{{ prescriptionData.chiefComplaint }}</td>
  </tr>

  <!-- 关键指标  -->
  <tbody>
    <tr>
      <td :rowspan="keyIndicatorsList.length + 1">关键指标</td>
    </tr>
    <tr v-for="(item, index) in keyIndicatorsList" :key="index">
      <td>{{ item.label }}</td>
      <td>{{ item.value }}</td>
    </tr>
  </tbody>
  <!-- 运动心肺功能测评 -->
  <tr>
    <td>运动心肺功能测评</td>
    <td></td>
    <td>{{ prescriptionData.cpet }}</td>
  </tr>

  <!-- 运动目标 -->
  <tr>
    <td>运动目标</td>
    <td></td>
    <td>{{ prescriptionData.exercisePrescriptionRespDTO.goal }}</td>
  </tr>
  <tr>
    <td>运动周期</td>
    <td></td>
    <td>{{ prescriptionData.exercisePrescriptionRespDTO.totalCycle }}周</td>
  </tr>
  <!-- 运动项目 -->
  <tr>
    <td colspan="3" align="center" style="font-weight: 600; text-align: center">运动项目</td>
  </tr>

  <!-- 运动子项 -->
  <tbody v-for="(item, index) in exerciseProjectList" :key="index">
    <tr>
      <td rowspan="7">{{ item.projectName }}</td>
    </tr>
    <tr>
      <td>运动分类</td>
      <td>{{ getDictLabel(DICT_TYPE.AI_EXERCISE_MAJOR_CATEGORY, item.majorCategory) }}</td>
    </tr>
    <tr>
      <td>运动量</td>
      <td>{{ item.volume }}{{ getDictLabel(DICT_TYPE.AI_EXERCISE_MEASUREMENT_UNIT, item.unit) }}</td>
    </tr>
    <tr>
      <td>运动频率</td>
      <td>{{ item.frequency }}{{ getDictLabel(DICT_TYPE.AI_EXERCISE_FREQUENCY, item.frequencyUnit) }}</td>
    </tr>
    <tr>
      <td>运动时间</td>
      <td>{{ item.duration }}{{ getDictLabel(DICT_TYPE.AI_EXERCISE_DURATION, item.durationUnit) }}</td>
    </tr>
    <tr>
      <td>运动强度</td>
      <td>{{ getDictLabel(DICT_TYPE.AI_EXERCISE_INTENSITY_LEVEL, item.intensity) }}</td>
    </tr>
    <tr>
      <td>是否分组</td>
      <td>{{ item.isGroup === 1 ? '是' : '否' }}</td>
    </tr>
  </tbody>
  <!-- 注意事项 -->
  <tr>
    <td :rowspan="tipsList.length + 1">注意事项</td>
  </tr>
  <tr v-for="(item, index) in tipsList" :key="index">
    <td>{{ item }}</td>
    <td></td>
  </tr>
</table>

3,js 如下:

js
import { ref, reactive, toRefs, onMounted, computed, onBeforeMount } from "vue";
import { prescriptionStoreWithOut } from "@/store/modules/prescription"; // vuex
import { getIntDictOptions, DICT_TYPE, getDictLabel } from "@/utils/dict";
import { PrescriptionInfoMatchingRespVO } from "@/api/prescription/info/index";

const prescriptionStore = prescriptionStoreWithOut(); // vuex

// 处方信息
const prescriptionData =
  ref <
  PrescriptionInfoMatchingRespVO >
  {
    exercisePrescriptionRespDTO: {
      cycleUnit: "", // 周期单位
      followUp: "", // 随访
      goal: "", //目标
      id: null, //主键ID
      items: [], //处方明细
      medicalId: null, //就诊ID
      stage: "", //阶段
      tips: "", //注意事项
      totalCycle: null //周期数
    }
  };

// 注意事项列表
const tipsList = computed(() => {
  if (prescriptionData.value.exercisePrescriptionRespDTO.tips) {
    return prescriptionData.value.exercisePrescriptionRespDTO.tips.split("\n");
  }
  return [];
});

// 运动项列表
const exerciseProjectList = computed(() => {
  return prescriptionData.value.exercisePrescriptionRespDTO.items || [];
});

// 关键指标列表
const keyIndicatorsList = computed(() => {
  if (prescriptionData.value.keyIndicators) {
    const indicatorsObject = JSON.parse(prescriptionData.value.keyIndicators);
    const indicatorsArray = Object.entries(indicatorsObject).map(([label, value]) => {
      // 处理空值的情况 给默认值
      if (value === null || value === "") {
        return { label, value: "" };
      }
      return { label, value };
    });
    return indicatorsArray;
  } else {
    return [];
  }
});

onBeforeMount(() => {
  if (prescriptionStore.prescriptionObject) {
    prescriptionData.value = prescriptionStore.prescriptionObject;
  }
});

4,css 样式如下:

css
<style scoped lang="scss">
  /* 重置表格默认样式 */
  table {
    // min-width: 700px; 在组件中直接更改宽度
    width: 100%;
    margin: 0 auto;
    border-collapse: collapse;
    td,
    th {
      border: 1px solid #ddd;
      padding: 5px;
      text-align: left;
      font-size: 14px;
      color: #525252;
    }

    /* 表头样式 */
    thead th {
      color: #333;
      text-align: center;
      padding: 8px;
      border: 1px solid #ddd;
      font-size: 16px;
    }

    .title th {
      background: #e7f5ff;
      color: #525252;
      text-align: center;
      font-size: 14px;
    }
  }

  /* 表格标题样式 */
  caption {
    font-size: 1.5em;
    text-align: left;
    padding: 10px;
    font-weight: bold;
  }

  /* 隔行变色 */
  table tr:nth-child(even) {
    // background-color: #f9f9f9;
  }

  /* 鼠标悬停样式 */
  table tr:hover {
    background-color: #f1f1f1;
  }

  /* 合并单元格时的样式 */
  // td[rowspan],
  // th[rowspan] {
  //   background-color: #e8e8e8;
  // }
</style>

我见青山多妩媚,料青山见我应如是。