最近在開發的Vue項目中,使用了iview第三方UI庫;對於表格組件的需求是最多的,可是在一些特定場景下,發現iview的表格組件沒有單元格合併與拆分的API,搜了一下發現不少同窗提問關於iview表格組件的單元格如何拆分和合並的問題。所以某家在此說下咱們在項目中如何填的這個坑。
由於咱們項目中首要的是單元格拆分的,所以以拆分爲例。基本思路就是:不在源碼層面進行修改;在外部對Table組件進行二次封裝。使用vue render函數對錶格組件的表格列配置數據進行動態改造,普通單元格渲染span標籤呈現數據,要拆分的單元格渲染原生table標籤;最後隱藏嵌套表格的邊框及調整相關原生表格樣式。
這裏注意以前打算用iview Table組件進行嵌套,可是發現修改table組件的樣式很是麻煩,並且沒有效果,一不當心就容易污染全局樣式,所以後來用原生table標籤完美解決樣式不可控問題。vue
1. 首先對於總體表格的列配置數據中有拆分的列進行添加split爲true的屬性。
數組
2.對於表格數據源進行子表格數據定義,也就是用數組的形式包含子表格數據iview
3.使用vue render函數動態渲染改造表格列結構,通單元格渲染span標籤呈現數據,要拆分的單元格渲染原生table標籤。函數
let vm = this; this.columnsList.forEach(item => { // 可編輯單元格 if (item.editable) { item.render = (h, param) => { let currentRow = this.thisTableData[param.index]; if (currentRow.editting) { // 正在編輯 if(item.split){ var childArray = currentRow[item.key]; var inputArray=[]; childArray.forEach(item => { var aa = h('Input', { style:{ width:'80%', 'margin-top':'10px', 'margin-bottom':'10px' }, props: { type: 'text', value: item.child }, on: { 'on-change' (event) { let key = param.column.key; var ddd = vm.edittingStore[param.index][key]; //item.child = event.target.value; //計算當前的索引 var currentIndex = childArray.indexOf(item); //更新數據 vm.edittingStore[param.index][key][currentIndex].child = event.target.value; } } }); inputArray.push(aa) var currentIndex = childArray.indexOf(item); if(currentIndex!==childArray.length-1){ var bb = h('hr',{ style:{ height:'1px', 'background-color':'#e9eaec', border:'none' } }) inputArray.push(bb) } }) return h('Row',inputArray) } else { return h('Input', { style:{ width:'80%' }, props: { type: 'text', value: currentRow[item.key] }, on: { 'on-change' (event) { let key = param.column.key; vm.edittingStore[param.index][key] = event.target.value; } } }); } } else { // 沒在編輯 if (this.editIncell) { // 單元格內編輯 return h('Row', { props: { type: 'flex', align: 'middle', justify: 'center' } }, [ h('Col', { props: { span: '16' } }, [ currentRow.edittingCell[param.column.key] ? cellInput(this, h, param, item) : h('span', currentRow[item.key]) ]), h('Col', { props: { span: '8' } }, [ currentRow.edittingCell[param.column.key] ? saveIncellEditBtn(this, h, param) : inCellEditBtn(this, h, param) ]) ]); } else { // 非單元格內編輯 if(item.split){ if(currentRow.childProject.length==1){ var value = currentRow.childProject[0].child; return h('span', value); } //用原生HTML標籤渲染 var trAarry=[]; var childArray = currentRow[item.key]; childArray.forEach(item => { var aa = h('tr',{},[ h('td',{ style:{ border:0, 'text-align':'center' } },item.child), ]) trAarry.push(aa) var currentIndex = childArray.indexOf(item); if(currentIndex!==childArray.length-1){ var bb = h('hr',{ style:{ height:'1px', 'background-color':'#e9eaec', border:'none' } }) trAarry.push(bb) } }) return h('table',{style:{ 'width':'100%', margin:0, border:0 }},trAarry) } else return h('span', currentRow[item.key]); } } }; } // 編輯和刪除按鈕 if (item.handle) { item.render = (h, param) => { let currentRowData = this.thisTableData[param.index]; let children = []; item.handle.forEach(item => { if (item === 'edit') { children.push(editButton(this, h, currentRowData, param.index)); } else if (item === 'delete') { children.push(deleteButton(this, h, currentRowData, param.index)); } }); return h('div', children); }; } }); }
4.完美實現了單元格拆分爲列的效果。
flex