问题描述
用Element Plus框架进行网站的搭建,用到了组件Table,进行列表数据的展示,但由于数据内容过长导致列换行了,自己感觉不美观,想处理下,由于也是才用这个框架对属性没有认真的看,导致走了不少弯路,其实框架本身已经给我们提供了处理办法。
弯路解决(不推荐)
自己参考了一个开源的一个插件:https://github.com/kaysonli/v-fit-columns,此插件可实现el-table-column宽度自适应但基于vue2开发的。但Element Plus框架是基于vue3的所以我对这个源码进行了修改以适应vue3。实际上就是自定义命令v-fit-columns来对列进行扩宽处理,具体可以参考下面的代码。
我的项目是基于Vue CLI构建的。
相关代码
import "../assets/style/fit-table-columns.css"
export default (app) => {
app.directive('fit-columns', {
created() {
},
beforeMount() {
},
mounted(el, binding) {
setTimeout(() => {
adjustColumnWidth(el, binding.value);
}, 300);
},
beforeUpdate() {
},
updated(el, binding) {
el.classList.add("r-table");
setTimeout(() => {
adjustColumnWidth(el, binding.value);
}, 300);
},
beforeUnmount() {
},
unmounted() {
}
})
}
function adjustColumnWidth(table, padding = 0) {
const colgroup = table.querySelector("colgroup");
const colDefs = [...colgroup.querySelectorAll("col")];
colDefs.forEach((col) => {
const clsName = col.getAttribute("name");
const cells = [
...table.querySelectorAll(`td.${clsName}`),
...table.querySelectorAll(`th.${clsName}`),
];
if (cells[0]?.classList?.contains?.("leave-alone")) {
return;
}
const widthList = cells.map((el) => {
return el.querySelector(".cell")?.scrollWidth || 0;
});
const max = Math.max(...widthList);
table.querySelectorAll(`col[name=${clsName}]`).forEach((el) => {
const oldWidth = el.offsetWidth;
if (max > oldWidth) {
el.setAttribute("width", max + padding);
}
});
});
}
// fit-table-columns.css
.el-table.r-table .cell {
display: inline-block;
white-space: nowrap;
width: auto;
overflow: auto;
}
.el-table.r-table .el-table__body-wrapper {
overflow-x: auto;
}
import {createApp} from 'vue'
import axios from 'axios'
import VueAxios from 'vue-axios'
import router from './router'
import fitTableColumns from './plugins/fit-table-columns'
import App from './App.vue'
const app = createApp(App).use(router)
app.use(VueAxios, axios)
fitTableColumns(app)
app.mount('#app')
// tableList.vue
<template>
<el-table :data="elTable.tableData"
stripe
border
height="250"
v-fit-columns
>
<el-table-column type="selection" width="55" />
<el-table-column type="index" label="序号" width="55"/>
<el-table-column v-for="(item,index) in elTable.tableLabels" :key="index"
:property="item.property"
:label="item.label"
:width="item.width"
>
</el-table-column>
</el-table>
</template>
<script>
export default {
name: "tableList",
data() {
return {
elTable: {
tableLabels: [
{label: '表名称', property: 'tableName'},
{label: '表描述', property: 'tableComment'},
{label: '创建时间', property: 'createTimeFormat'},
{label: '更新时间', property: 'updateTimeFormat'}
],
tableData: [{
"createTimeFormat": "2022-04-07 15:27:06",
"updateTimeFormat": null,
"tableName": "oauth2_authorization_consent",
"tableComment": ""
},
{
"createTimeFormat": "2022-04-07 15:27:31",
"updateTimeFormat": "2022-05-25 09:34:08",
"tableName": "oauth2_registered_client",
"tableComment": ""
}]
}
}
}
}
</script>
换行前table样式
表名称是换行的
处理后table样式
确实不换行了,列变宽了可以展示全部的数据了,但感觉还是不是很好,因为如果数据很多岂不是行变得很长。还有就是首次加载时,updated方法会执行多次导致table频繁闪动。
官方处理方式(推荐)
有这么个属性:show-overflow-tooltip,文档说明: 若需要单行显示可以使用 show-overflow-tooltip 属性,它接受一个 Boolean, 为 true 时多余的内容会在 hover 时以 tooltip 的形式显示出来。
修改代码
<template>
<el-table :data="elTable.tableData"
stripe
border
height="250"
>
<el-table-column type="selection" width="55" />
<el-table-column type="index" label="序号" width="55"/>
<el-table-column v-for="(item,index) in elTable.tableLabels" :key="index"
:property="item.property"
:label="item.label"
:width="item.width"
show-overflow-tooltip
>
</el-table-column>
</el-table>
</template>
页面效果
加了show-overflow-tooltip我们再来看一看效果,列没有加宽,而是把溢出的数据用省略号替换并用Tooltip 组件的文字提示。 感觉不错,反正达到我想要的效果。
总结
一定要用认真看官方的文档,以免走弯路。但我这次还好起码学到了vue3关于自定义命令的相关知识。
|