可配置字段类型el-table表头自适应的两种方案
项目场景:可以选择展示哪些label的可配置字段类型el-table:
由于要求做中英双版,因此表头自适应这个功能尤为重要(有些英文label实在太长了)
(已经把项目页面涂了马赛克,不知道还会不会被举报,新人写博客这方面不是很懂(雾))
①理想情况:满足所有字段的表头宽度都能自适应,且如果选择显示的字段太少,改为el-table默认的自动拉伸;如果字段太多,显示横向滚动条。
表头自适应计算width方法:
flexColumnWidth (str) { // 表头宽度自适应方法
if (!this.widthFlag) { // 第一次进入flexColumnWidth直接进入else,然后在此基础上判断自适应后的内容总宽度是否超过表格宽度,超过的话widthFlag变true并再一次进入flexColumnWidth方法,使所有列的宽度比变为auto自动拉伸
return 'auto'
} else {
if (str === '操作') { // 有些标题短但内容特别长的需要再次定制化
return 100
}
let flexWidth = 0
for (const char of str) {
if ((char >= 'A' && char <= 'Z') || (char >= 'a' && char <= 'z')) {
// 如果是英文字符,为字符分配10个单位宽度
flexWidth += 10
} else if (char >= '\u4e00' && char <= '\u9fa5') {
// 如果是中文字符,为字符分配25个单位宽度
flexWidth += 25
} else {
// 其他种类字符,为字符分配11个单位宽度
flexWidth += 11
}
}
if (flexWidth < 80) {
// 设置最小宽度
flexWidth = 80
}
// if (flexWidth > 250) {
// // 设置最大宽度
// flexWidth = 250
// }
return flexWidth
}
},
el-table-column绑定该width方法
<el-table-column
prop="caozuo"
label="操作"
:width="flexColumnWidth('操作')"
v-if="checkedCitieszi.indexOf('操作')!==-1"
show-overflow-tooltip>
</el-table-column>
el-checkbox绑定判断调整表头宽度方法checkWidth
<el-checkbox-group v-model="checkedCitieszi">
<el-checkbox v-for="city in citiezi" :label="city" :key="city" @change="checkWidth">{{city}}</el-checkbox>
</el-checkbox-group>
判断调整表头宽度方法checkWidth(注意因为有渲染时间所以建议给el-table加上v-loading=“loading”属性)
checkWidth () {
this.loading = true
this.widthFlag = true // 先统一让表头自适应,方便判断表格内容宽度小于还是大于表格框框宽度
setTimeout(() => { // 考虑到表格本身的渲染时间,需要延时进行操作以获取渲染后的实际宽度,否则获取的是修改配置字段之前的老宽度
let theTable = document.getElementById('myTable') // 需要进行表头自适应的table对象
let body = theTable.getElementsByClassName('el-table__body') // 用于获取表格框框宽度的对象
let bodyWrapper = theTable.getElementsByClassName('el-table__body-wrapper') // 用于获取表格实际内容宽度的对象
// console.log(theTable.offsetWidth, body[0].clientWidth)
if ((theTable.offsetWidth) >= body[0].clientWidth) {
this.widthFlag = false // 如果自适应后的表格内容小于表格框框宽度,此时最右边会出现没有线的空白范围,此时改为el-table自带的自动拉伸功能
bodyWrapper[0].style.overflowX = 'hidden' // 如果自适应后的表格内容小于表格框框宽度,隐藏横向滚动条
} else {
bodyWrapper[0].style.overflowX = 'auto' // 如果自适应后的表格内容大于表格框框宽度,显示横向滚动条
}
this.loading = false
}, 500)
}
初始化判断标志widthFlage
data () {
return {
loading: false,
widthFlag: true, // 判断表头自适应宽度后是否小于表格宽度,小于的话取消自适应改为自动拉伸
}
}
el-tabel绑定id及loading
<el-table
id="myTable"
v-loading="loading">
</el-table>
在初始化表格时也要加上表头自适应判断方法
mounted () {
// 进入页面先loading
this.loading = true
// 获取数据的方法
this.getTableDates(this.sizes, this.currents)
// 跳过渲染时间延时判断
setTimeout(() => {
this.checkWidth()
}, 500)
},
②特殊情况:在①的基础上,如果有多个很短的字段,会出现自适应后小于表格框框宽度但是自动拉伸后很长的字段反而被掐住了的特殊情况。这种情况改为次选方案PlanB,如果自适应后小于表格框框宽度,不自动拉伸而改为空白部分用空白列填充.
在el-table的末尾加上空白列
<el-table-column
label=""
v-if="blankShow">
</el-table-column>
初始化空白列是否出现的判断标志
data () {
return {
loading: false,
blankShow: true, // 初始化空白列是否出现的判断标志
}
}
判断调整表头宽度方法checkWidth去掉一层判断
flexColumnWidth (str) { // 表头宽度自适应方法
if (str === '状态') {
// 有些标题短但内容特别长的需要再次定制化
return 100
}
let flexWidth = 0
for (const char of str) {
if ((char >= 'A' && char <= 'Z') || (char >= 'a' && char <= 'z')) {
// 如果是英文字符,为字符分配13个单位宽度
flexWidth += 13
} else if (char >= '\u4e00' && char <= '\u9fa5') {
// 如果是中文字符,为字符分配30个单位宽度
flexWidth += 30
} else {
// 其他种类字符,为字符分配11个单位宽度
flexWidth += 11
}
}
if (flexWidth < 80) {
// 设置最小宽度
flexWidth = 80
}
// if (flexWidth > 250) {
// // 设置最大宽度
// flexWidth = 250
// }
return flexWidth
},
判断调整表头宽度方法checkWidth稍作修改,不使用widthFlag改为控制blankShow
// 表格初始化以及选择配置字段后触发,检查是否使用表头自适应方法,控制用于填充的空白列是否show,是否出现横向滚动条
checkWidth () {
this.loading = true
this.blankShow = false // 先统一隐藏空白列,方便判断表格内容宽度是否小于表格框框宽度
setTimeout(() => { // 考虑到表格本身的渲染时间,需要延时进行操作以获取渲染后的实际宽度,否则获取的是修改配置字段之前的老宽度
let theTable = document.getElementById('myTable') // 需要进行表头自适应的table对象
let body = theTable.getElementsByClassName('el-table__body') // 用于获取表格框框宽度的对象
let bodyWrapper = theTable.getElementsByClassName('el-table__body-wrapper') // 用于获取表格实际内容宽度的对象
// console.log(theTable.offsetWidth, body[0].clientWidth)
// 为了防止不加空白列会小于表格框框宽度(最右边会空出一段没有线的范围)而加了空白列会超出表格框框(此时内容超出但并不显示滚动条)的尴尬中间情况
// 需要预支50宽度(空白列最小宽度)的差量用于判断,防止加了空白列会超出表格框框效果,尽量引导向内容宽度小于表格框框宽度然后加上空白列填充这种情况(即下面的第一种情况)
if ((theTable.offsetWidth) >= (body[0].clientWidth + 50)) {
this.blankShow = true
bodyWrapper[0].style.overflowX = 'hidden'
} else {
bodyWrapper[0].style.overflowX = 'auto'
}
this.loading = false
}, 500)
}
Smile and let everyone know that today you’re a lot stronger than you were yesterday.
用微笑告诉世人,今天的你比昨天更加强大。