登录
登录 注册新账号
注册
已有账号登录

这两天有个需求,要合并单元格,由于整个页面就一个表格,我就不想引入其他的js了,在网上也查了,别人写的看不懂啊o(TヘTo),于是就自己写了一个,感觉循环好多啊,formateList这个方法的代码还能优化么,

new Vue({
  el: '#app',
  data() {
    return {
        data: [...]
    }
  },
  created() {
    this.formateList(this.data, 'boatChinesename')
  },
  methods: {
      formateList(list, value) {
          let index = 0;
          let newList = list.reduce((prv, data) => {
              if (prv.some(itm => itm[value] === data[value])) {
                  data.isShow = false
              } else {
                  let merger = list.filter(item => item[value] === data[value])
                  data.rowspan = merger.length
                  data.isShow = true
                  data.index = index++
              }
              return [...prv, data]
          }, [])
          console.log(newList);
         this.data = newList
      }
  },
})

html
<div id="app">
<h3></h3>
<div class="content">
<table style="width: max-content;">
  <thead>
    <tr>
        <th>序号</th>
        <th>船名</th>
        <th>货名</th>
        <th>货代</th>
        <th>委托人</th>
        <th>场区</th>
    </tr>
  </thead>
  <tbody>
    <tr v-for="(itm, index) in data" :key="itm.id">
    <td v-if="itm.isShow" :rowspan="itm.rowspan">{{itm.index}}</td>
    <td v-if="itm.isShow" :rowspan="itm.rowspan">{{itm.boatChinesename}}</td>
    <td>{{itm.goosType}}</td>
    <td>{{itm.consignee}}</td>
    <td>{{itm.customerShortname}}</td>
    <td>{{itm.pile}}</td>
    </tr>
</tbody>
<tfoot>
    <tr>
        <td>合计</td>
        <td colspan="2"></td>
        <td></td>
     <td></td>
     <td></td>
    </tr>
</tfoot>
</table>
</div>
</div>

图片描述

2 个回答
(function() {
    var list = [{
            id: 1,
            name: "111"
        },
        {
            id: 1,
            name: "111"
        },
        {
            id: 2,
            name: "111"
        },
        {
            id: 2,
            name: "111"
        },
        {
            id: 3,
            name: "111"
        },
        {
            id: 3,
            name: "111"
        },
        {
            id: 4,
            name: "111"
        },
    ];

    const logs = Array.from(GetMergeList(list, "id"));
    console.log(logs);
})();

/**
 * 合并单元格
 * @param {any[]} rows
 * @param {string} field 合并字段
 * @returns {number[]} [起始, 长度]
 */
function* GetMergeList(rows, field) {
    var k = 0;

    for (let i = 1; i < rows.length; i++) {
        var curid = rows[i][field];
        var preid = rows[i - 1][field];
        if (curid !== preid) {
            yield [k, i - k];
            k = i;
        }
    }

    if (k !== rows.length) {
        yield [k, rows.length - k];
    }
}

list循环1~2次完成排序和合并

console.log((
/**
 * @param {array} list 别问
 * @param {string} keyName 合并的键名
 * @returns {array} 会删除被合并的键值和index 不用v-if判断直接输出
 */
(list, keyName, indexName = 'index')=> {
  let map = {},
    reList = [],
    todoList = [],
    index = 0;
  for (let k = -1; list[++k];) {
    let t_k = list[k],
      map_k = map[t_k[keyName] || NaN];
      let new_t_k = Object.assign({}, t_k)
    if (map_k === undefined) {
      map[t_k[keyName]] = k
      new_t_k[indexName] = index++
      reList.push(new_t_k)
    } else if (map_k != k) {
      delete new_t_k[keyName]
      reList[map_k].rowspan = reList[map_k].rowspan + 1 || 2
      todoList.unshift({
        index: map_k,
        item: new_t_k
      })
    }
  }
  for (let t = -1; todoList[++t];) {
    let t_t = todoList[t]
    reList.splice(t_t.index + 1, 0, t_t.item)
  }
  return reList
})([{
  name: 'a',
  value: 1
}, {
  name: 'b',
  value: 2
}, {
  name: 'a',
  value: 3
}, {
  name: 'b',
  value: 4
}, {
  name: 'b',
  value: 5
}, {
  name: 'c',
  value: 6
}], 'name'))
撰写答案