Vue + iview-ui 遇到 iview內(nèi)的table沒(méi)有原生table那種列寬自適應(yīng)功能,在iview table API中并沒(méi)有找到自適應(yīng)的接口
同樣锌唾,Element table雖然擁有 fit 這個(gè)屬性但是使用上并沒(méi)發(fā)現(xiàn)有任何作用疮方,在Element官方github上
issue #4159 大部分人討論方向都是通過(guò)遍歷計(jì)算每列最大寬度玷氏,但是當(dāng)數(shù)據(jù)多的時(shí)候性能會(huì)受到影響。
后來(lái)官方關(guān)掉了這個(gè)票伤塌,需要開(kāi)發(fā)人員自行解決。
不管是Element還是iview 針對(duì)table的封裝,都會(huì)自動(dòng)加入colgroup col 標(biāo)簽,并且對(duì)table加上table-layout: fixed已達(dá)到固定列寬的功能蜕煌,反之若沒(méi)有這兩個(gè)條件剖张,那么table自然就和原生table一樣擁有自適應(yīng)列寬的功能切诀。
- 從css角度上 把colgroup col標(biāo)簽要屏蔽掉并且table 的table-layout: fixed css屬性還原成auto就達(dá)到了列寬自適應(yīng)的功能。
<Table
id="devStepTaskList"
class="auto-column-size-table"
ref="autoTable"
:data="data"
maxHeight="220"
></Table>
.auto-column-size-table table {
table-layout: auto;
}
.auto-column-size-table table colgroup col {
display: none;
}
加上這兩個(gè)css后table便可以自適應(yīng)列寬了搔弄,需要的話可以再加上個(gè)列最小寬度幅虑,防止空值情況表頭被擠。
- 但是 由于某些復(fù)雜功能的原因 iview和Element的 table的構(gòu)建表頭thead 和tbody是分開(kāi)的兩個(gè)table顾犹,所以會(huì)出現(xiàn)自適應(yīng)寬度頭身不等情況倒庵。有一種處理方法是在tbody自適應(yīng)后的每一列寬度賦給表頭thead的th上,具體如下
//直接取第一行的就行炫刷,因?yàn)槊恳恍辛袑挾家粯? let tableDom = document.getElementById('devStepTaskList')
let tds = tableDom.getElementsByClassName('ivu-table-row')[0].children
let ths = tableDom.getElementsByTagName('th')
let tdArr = []
// 這里為了方便理解直接for循環(huán)處理
for (let i = 0; i < tds.length; i++) {
tdArr.push(tds[i].offsetWidth) // 把每一列循環(huán)到的width存入數(shù)組里
}
for (let i = 0; i < ths.length; i++) {
ths[i].style.width = tdArr[i] + 'px' // 直接寬度賦值
}
現(xiàn)在表現(xiàn)一致了擎宝,重點(diǎn)是dom取值找準(zhǔn)了就行,代碼里用的iviewUI浑玛,Element處理同理找這個(gè)tr.el-table__row
具體找子集可能有區(qū)別绍申,但是核心都是找到td的offsetWidth賦給th的width。
- 這時(shí)還有個(gè)問(wèn)題顾彰,如果設(shè)置最大高度极阅,出現(xiàn)滾動(dòng)條的話又會(huì)出現(xiàn)頭尾對(duì)不齊的狀態(tài),所以要先把tbody內(nèi)的table寬度減去滾動(dòng)條寬度再進(jìn)行上述賦值操作拘央。注意是tbody內(nèi)的table
let tableDom = document.getElementById('devStepTaskList')
if (this.data.length > 5) { // data.length 數(shù)據(jù)量大于最大顯示數(shù)據(jù)量涂屁,出現(xiàn)滾動(dòng)條條件
let tables = tableDom.getElementsByClassName('ivu-table-body')
let table = tables[0].children[0]
table.style.width = table.offsetWidth - 17 + 'px' // 減去滾動(dòng)條寬度
}
let tds = tableDom.getElementsByClassName('ivu-table-row')[0].children
let ths = tableDom.getElementsByTagName('th')
let tdArr = []
for (let i = 0; i < tds.length; i++) {
tdArr.push(tds[i].offsetWidth)
}
for (let i = 0; i < ths.length; i++) {
ths[i].style.width = tdArr[i] + 'px'
}
- 最后,這部分處理首先在watch data時(shí)觸發(fā)灰伟,防止后續(xù)增刪改導(dǎo)致的寬度變動(dòng)
watch: {
data: function (newVal, oldVal) {
this.$nextTick(() => {
// 上述代碼
})
}
},
可以的話在共同函數(shù)進(jìn)行封裝拆又,需要表格的地方進(jìn)行調(diào)用儒旬。
然后需要監(jiān)聽(tīng)窗口變動(dòng)window.resize導(dǎo)致的表格寬度變化
window.addEventListener('resize', this.listenTableColumnResize) // 上述代碼封裝后的函數(shù),可以在setTimeout執(zhí)行
網(wǎng)上的方法大都是計(jì)算寬度再進(jìn)行賦值帖族,感覺(jué)像官方人員說(shuō)的栈源,不應(yīng)該舍近求遠(yuǎn)。所以這里列寬自適應(yīng)主要就兩句css,剩下都是為了對(duì)齊竖般。
網(wǎng)上并沒(méi)看到類似的答案甚垦,所以這里提出了一種思路。
希望能幫到遇到同樣的問(wèn)題的人