<el-table v-tableFit></el-table>
)Vue.directive("tableFit", { bind(el, binding, vnode) { setTimeout(() => { setColumnWidth(el, vnode); }, 0) }, //指令所在組件的 VNode 及其子 VNode 所有更新後調用。 componentUpdated(el, binding, vnode) { setTimeout(() => { setColumnWidth(el, vnode); }, 0) }, }); function setColumnWidth(table, vnode) { //中文和全角正則 const CN = new RegExp("[\u4E00-\u9FA5]|[\uFF00-\uFFFF]"); const NUM = new RegExp("[0-9]"); //中文和全角字體的像素寬度比例 const CN_RATE = 1.1 //數字字體的像素寬度比例 const NUM_RATE = 0.7 //其餘字體的像素寬度比例 const OTHER_RATE = 0.6 const columns = vnode.child.columns.slice() //忽略序號、多選框、已設置寬度的表頭 for (let i = columns.length - 1; i >= 0; i--) { if (columns[i].width || columns[i].type === 'index' || columns[i].type === 'selection') { columns.splice(i, 1) } } const colDefs = columns.map(item => item.id) //設置每列寬度 colDefs.forEach((clsName, index) => { //colgroup中 和 表頭標籤的class名相同 經過class尋找相同列 const cells = [ ...table.querySelectorAll(`.el-table__body-wrapper td.${clsName}`), ...table.querySelectorAll(`th.${clsName}`), ]; const widthList = cells.map((el) => { const cell = el.querySelector(".cell") if (cell) { let fontSize = parseInt(window.getComputedStyle(cell,null).fontSize) fontSize = fontSize ? fontSize : 14 //處理多行內容取最大寬度 let strList = cell.innerText.split('\n') let strWidth = strList.map(item => { let width = 0 //計算每一個字符的寬度 for(let str of item) { if(CN.test(str)) { width += fontSize * CN_RATE }else if(NUM.test(str)) { width += fontSize * NUM_RATE }else { width += fontSize * OTHER_RATE } } return Math.ceil(width) }) return Math.max(...strWidth) } else { return 0 } }); //取一列中的最大寬度 const max = Math.max(...widthList); if (max !== 0) { //在表格數據中設置minWidth 防止尺寸變化從新計算原來的寬度 columns[index].minWidth = max + 20 table.querySelectorAll(`col[name=${clsName}]`).forEach((el) => { el.setAttribute("width", max + 20); }); } }); //設置完後調用el-table方法更新佈局 vnode.child.doLayout() tableRevise(table) }
沒有錯位的能夠忽略javascript
//修正el-table錯位 function tableRevise(table) { const tableWrapper = table.querySelector('.el-table__body-wrapper') const tableBody = table.querySelector('.el-table__body') const colgroup = table.querySelector("colgroup"); /** * (如下數值爲滾動條高度,能夠本身根據狀況經過class從新修改) */ //內容大於容器時 if (tableBody.clientWidth > tableWrapper.offsetWidth) { //設置x軸滾動 tableWrapper.style.overflowX = 'auto' //解決固定列錯位 (沒有錯位的能夠忽略如下內容) let fixedWrap = table.querySelectorAll('.el-table .el-table__fixed-body-wrapper') if (fixedWrap.length > 0) { fixedWrap.forEach(item => { item.style.paddingBottom = 8 + 'px' }) } //解決固定列覆蓋滾動條 let fixed_left = table.querySelector('.el-table .el-table__fixed') let fixed_right = table.querySelector('.el-table .el-table__fixed-right') if (fixed_left) { fixed_left.style.height = 'calc(100% - 8px)' } if (fixed_right) { fixed_right.style.height = 'calc(100% - 8px)' } //解決表頭偏移 //沒有原生的gutter時本身新增一個 const gutter = colgroup.querySelector(`col[name=gutter]`) const gutterx = colgroup.querySelector(`col[name=gutterx]`) if (!gutter && !gutterx) { let col = document.createElement('col') col.setAttribute('name', 'gutterx') col.setAttribute('width', '8') colgroup.appendChild(col) } } }