矩阵字符串配置任意合并表格布局

效果

在这里插入图片描述

核心

布局配置矩阵(以下为多个模式),可以使用|\n表示矩阵行

const gridArr = [
`
1,2,a,b
3,4,a,b
5,6,a,b
`,
`
1,2
3,4
5,6
`,
`
1,2,3,4
3,4
`
]

任意横向或者纵向相同的字符表示一个合并块

使用

<CalcTable grid="1,2,a,b|3,4,a,b|5,6,a,b" >
      <span>姓名</span>
      <span>李牧</span>
      <span>证件</span>
      <span>img</span>
      <span>性别</span>
      <span></span>
      <span>身份证号</span>
      <span>3707783199609282223</span>
</CalcTable>

代码

因为是在vue开发中有些地方使用表格布局,后来想偷懒不写tr,td,然后就有了以下代码,可扩展为组件化的任意布局方案管理

<script>
/*
* 通过输入表格标记矩阵自动生成合并后的表格结构
*
* 可扩展为组件化的任意布局
* */
export default {
  name: "CalcTable",
  data() {
    return {
    }
  },
  props: {
    grid: {
      type: String,
      default: '1,2,3,4|5,5,3,4|5,5,6,7|8,9,10,1|7,9,1,2'
    }
  },
  render(h) {
    const vm = this
    const innerVNode = vm.$scopedSlots.default()
    let renderIndex = 0
    //1)计算matrix
    const matrix = vm.gridStrToMatrix()

    //2)双层循环遍历matrix,及逐行逐列
    return h('table', {}, matrix.map(row => {
      return h('tr',
        {},
        [
          h('td',{
            class:{
              fill:true
            }
          }),
          row.filter(d => d).map(cell => {
            return h('td', {
              attrs: {
                colspan: cell[1],
                rowspan: cell[0]
              }
            }, renderIndex<innerVNode.length ? [innerVNode[renderIndex++]] : [])
          })
        ])
    }))
  },
  methods: {
    gridStrToMatrix() {
      const vm = this
      //以行列表示每个字符位置
      let rows = vm.grid.replace(/ /g,'').split(/\n|\|/).filter(d=>d)
      let matrix = new Array(rows.length)

      rows.forEach((row, index) => {
        matrix[index] = row.split(',')
      })
      //遍历所有进行合并标记
      let rowIndex, colIndex, row, cell
      for (rowIndex = 0; rowIndex < matrix.length; rowIndex++) {
        row = matrix[rowIndex]
        for (colIndex = 0; colIndex < row.length; colIndex++) {
          cell = matrix[rowIndex][colIndex]
          // console.log(cell)
          if (cell != null) {
            let span = [1, 0]
            for (let i = colIndex; i < row.length; i++) {
              if (row[i] == cell) {
                span[1]++
                row[i] = null
              }
            }
            for (let i = rowIndex; i < matrix.length; i++) {
              if (matrix[i][colIndex] == cell) {
                span[0]++
                matrix[i][colIndex] = null
              }
            }
            for (let i = rowIndex; i < rowIndex + span[0]; i++) {
              for (let j = colIndex; j < colIndex + span[1]; j++) {
                matrix[i][j] = null
              }
            }
            matrix[rowIndex][colIndex] = span
          }
        }
      }
      return matrix

    }
  }
}
</script>

<style scoped>
  td {
    border: 1px solid #000;
    padding: 20px;
  }

  table {
    border-collapse: collapse;
  }

  .fill {
    padding-left: 0;
    padding-right: 0;
    border: 0;
  }
</style>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值