一、a-table合并单元格

1、根据mainTaskId 合并,定义一个方法来记录每个 mainTaskId 的出现次数和它在表格中首次出现的位置

setupSpanMap(data) {  // data是组件的数据源 dataSource
    const spanMap = {};
    let lastTaskId = null;
    let lastIndex = 0;

    data.forEach((row, index) => {
      if (row.mainTaskId !== lastTaskId) {
        if (lastTaskId !== null) {
          spanMap[lastIndex] = index - lastIndex;  // 设置之前mainTaskId的span
        }
        lastIndex = index;
        lastTaskId = row.mainTaskId;
      }

      // 根据批次合并检查项目
      // 开始合并的下标
      let start = 0
      // 合并的行数
      let count = 1
      // 上一行的检测项
      let perItem = null
      // 上一行的批次
      let perBath = null
      // 根据批次合并检查项目
      if (index == 0) {
        perItem = row.inspectionItem
        perBath = row.sampleBatch
      } else if (row.inspectionItem == perItem && row.sampleBatch == perBath) {
        count++
      } else {
        this.inspectionItemMap[start] = count
        // 重置从下一个不一样的检测项的下标
        start = start + count
        // 重置合并的行数
        count = 1
      }
      // 当长度是最后一个的时候push一次
      if (index == data.length - 1) {
        this.inspectionItemMap[start] = count
      }
      perBath = row.sampleBatch
      perItem = row.inspectionItem
    });

    if (lastTaskId !== null) {
      spanMap[lastIndex] = data.length - lastIndex;  // 最后一组mainTaskId
    }
    this.spanMap = spanMap;
    this.dataSource = data  // 处理完上序操作再给dataSource赋值
  },

2、需要修改组件绑定列(column)的 customRender 方法来动态计算 rowSpan。包括:

  • 在首次遇到新的 mainTaskId 时设置 rowSpan

  • 对后续相同的 mainTaskId 设置 rowSpan 为 0。

{
     title: '样品单号',
     align: 'center',
     dataIndex: 'mainTaskId',
     customRender: (value, row, index) => {
        const span = this.spanMap[index] || 0 // 获取当前索引的rowSpan
        const obj = {
          children: value,
             attrs: {},
          }
          if (span > 0) {
             obj.attrs.rowSpan = span
          } else {
             obj.attrs.rowSpan = 0 // 相同mainTaskId的其他行
          }
          return obj
     },
},

二、 在jEditTable里面的插槽<a-select>组件的options下拉框选了值但是在选择框内没有值

  • 没有正确使用setValue方法赋值

  • ​区分下拉框的text和label

三、格式化北京时间

// 格式化时间
formatDateTime(date) {
   // 获取本地时区偏移量
   const offset = date.getTimezoneOffset() * 60000 // 转换为毫秒
   // 创建一个新的日期对象,已根据时区偏移调整
   const localDate = new Date(date.getTime() - offset)
   // 将调整后的日期转换为 ISO 格式的字符串,并进行格式化
   return localDate.toISOString().replace('T', ' ').substring(0, 19)
},

// 调用
const now = new Date()
let time = this.formatDateTime(now)

四、set去重

let inspectionMethod = 'apple,apple,orange,banana,apple,banana'
let inspectionMethods = [...new Set(inspectionMethod.split(','))] // ['apple','orange','banana']

五、同一页面多模版打印标签点击第一个后面的标签显示空白bug

在preview.vue文件中,不同的标签应该给不同的id类名

<div id="preview_content_qy"></div> <!-- 第一个模版标签容器 -->
<div id="preview_content"></div>  <!-- 第二个模版标签容器 -->
// 获取容器填充内容
$('#preview_content_qy').html(hiprintTemplate.getHtml(printData))   
$('#preview_content').html(hiprintTemplate.getHtml(printData))

六、jEditable组件结合switch开关 插槽

<j-editable-table :ref="refKeys[0]" :loading="matBomDtTable.loading" :columns="matBomDtTable.columns" :dataSource="matBomDtTable.dataSource" :maxHeight="300" :disabled="formDisabled" :rowNumber="true" :rowSelection="true" :actionButton="true">
   <template v-slot:isRequired="props">
       <!-- 使用:checked绑定开关 -->
       <!-- 一般其他插槽使用 :value="props.text"绑定值 -->
       <a-switch :checked="props.text == 1" :disabled="formDisabled" @change="(value) => handleRequired(value, props)" />
   </template>
</j-editable-table>
handleRequired(value, row) {
   // 根据开关得值给组件字段赋值
   this.$refs.matBomDt.setValues([{ rowKey: row.rowId, values: { isRequired: value ? 1 : 0} }])
},

七、删除对象中的字段

delete this.model.testItems  // delete  obj.属性名

八、当页面有多个滚动条时,a-select组件的下拉框停留在页面,没有跟随组件位置变化

通过 getPopupContainer 属性可以指定渲染下拉选项的父容器。将其设置为渲染在组件的父级元素中

<a-select
    v-model="value"
    show-search
    :options="valueOption"
    :filter-option="filterOption"
    :getPopupContainer="triggerNode => triggerNode.parentNode" /> 
// filterOption根据下拉框的text进行搜索筛选,在methods中定义
filterOption(input, option) {
  return option.componentOptions.children[0].text.toLowerCase().indexOf(input.toLowerCase()) >= 0
},

九、根据value属性对数组对象去重

const array = [
    { text: 1, value: 1 },
    { text: 1, value: 1 },
    { text: 2, value: 2 },
    { text: 3, value: 1 }
];
// 使用Map来进行去重
const uniqueArray = Array.from(new Map(array.map(item => [item.value, item])).values());

十、从数组对象 B 中获取 A 数组中ID对应的对象

const A = [1, 2, 3]; // A是部分id的数组
const B = [
    { id: 1, name: 'Object 1' },
    { id: 2, name: 'Object 2' },
    { id: 3, name: 'Object 3' },
    { id: 4, name: 'Object 4' }
]; // B是包含对象的数组
const result = B.filter(obj => A.includes(obj.id));