效果
核心
布局配置矩阵(以下为多个模式),可以使用|
或\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 = thisconst innerVNode = vm.$scopedSlots.default()let renderIndex = 0//1)计算matrixconst 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, cellfor (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>