mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-02 15:30:25 +08:00
refactor: 表格宽度自适应宽度计算方式调整
This commit is contained in:
@@ -52,4 +52,57 @@ export function letterAvatar(name: string, size = 60, color = '') {
|
||||
dataURI = canvas.toDataURL();
|
||||
canvas = null;
|
||||
return dataURI;
|
||||
};
|
||||
|
||||
/**
|
||||
* 计算文本所占用的宽度(px) -> 该种方式较为准确
|
||||
* 使用span标签包裹内容,然后计算span的宽度 width: px
|
||||
* @param str
|
||||
*/
|
||||
export function getTextWidth(str: string) {
|
||||
let width = 0;
|
||||
let html = document.createElement('span');
|
||||
html.innerText = str;
|
||||
html.className = 'getTextWidth';
|
||||
document?.querySelector('body')?.appendChild(html);
|
||||
width = (document?.querySelector('.getTextWidth') as any).offsetWidth;
|
||||
document?.querySelector('.getTextWidth')?.remove();
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取内容所需要占用的宽度
|
||||
*/
|
||||
export function getContentWidth(content: any): number {
|
||||
if (!content) {
|
||||
return 50;
|
||||
}
|
||||
// 以下分配的单位长度可根据实际需求进行调整
|
||||
let flexWidth = 0;
|
||||
for (const char of content) {
|
||||
if (flexWidth > 500) {
|
||||
break;
|
||||
}
|
||||
if ((char >= '0' && char <= '9') || (char >= 'a' && char <= 'z')) {
|
||||
// 小写字母、数字字符
|
||||
flexWidth += 9.3;
|
||||
continue;
|
||||
}
|
||||
if (char >= 'A' && char <= 'Z') {
|
||||
flexWidth += 9;
|
||||
continue;
|
||||
}
|
||||
if (char >= '\u4e00' && char <= '\u9fa5') {
|
||||
// 如果是中文字符,为字符分配16个单位宽度
|
||||
flexWidth += 20;
|
||||
} else {
|
||||
// 其他种类字符
|
||||
flexWidth += 8;
|
||||
}
|
||||
}
|
||||
// if (flexWidth > 450) {
|
||||
// // 设置最大宽度
|
||||
// flexWidth = 450;
|
||||
// }
|
||||
return flexWidth;
|
||||
};
|
||||
@@ -43,7 +43,7 @@
|
||||
</div>
|
||||
<!-- 这里做的是一个类似于折叠面板的功能 -->
|
||||
<div class="query-content" :class="isOpenMoreQuery ? 'is-open' : ''">
|
||||
<el-form :model="props.queryForm" label-width="70px" style="display: flex; flex-wrap: wrap;">
|
||||
<el-form :model="props.queryForm" label-width="auto" style="display: flex; flex-wrap: wrap;">
|
||||
<el-form-item :label="item.label" style="margin-right: 20px; margin-bottom: 0px;"
|
||||
v-for="item in props.query?.slice(defaultQueryCount)" :key="item.prop">
|
||||
|
||||
@@ -224,7 +224,7 @@ watch(() => props.data, (newValue: any) => {
|
||||
if (newValue.length > 0) {
|
||||
props.columns.forEach(item => {
|
||||
if (item.autoWidth && item.show) {
|
||||
item.minWidth = TableColumn.flexColumnWidth(item.prop, item.label, props.data) as any
|
||||
item.minWidth = TableColumn.flexColumnWidth(item.prop, item.label, props.data) + item.addWidth
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { dateFormat } from '@/common/utils/date';
|
||||
import { getTextWidth } from '@/common/utils/string';
|
||||
|
||||
export class TableColumn {
|
||||
|
||||
@@ -17,6 +18,11 @@ export class TableColumn {
|
||||
*/
|
||||
autoWidth: boolean = true;
|
||||
|
||||
/**
|
||||
* 自动计算宽度时,累加该值(可能列值会进行转换添加图标等,宽度需要比计算出来的更宽些)
|
||||
*/
|
||||
addWidth: number = 0;
|
||||
|
||||
/**
|
||||
* 最小宽度
|
||||
*/
|
||||
@@ -58,6 +64,11 @@ export class TableColumn {
|
||||
return this;
|
||||
}
|
||||
|
||||
setAddWidth(addWidth: number): TableColumn {
|
||||
this.addWidth = addWidth
|
||||
return this;
|
||||
}
|
||||
|
||||
setSlot(slot: string): TableColumn {
|
||||
this.slot = slot
|
||||
return this;
|
||||
@@ -95,16 +106,15 @@ export class TableColumn {
|
||||
* @param label 表头label也参与宽度计算
|
||||
* @returns 列宽度
|
||||
*/
|
||||
static flexColumnWidth = (str: any, label: string, tableData: any) => {
|
||||
static flexColumnWidth = (str: any, label: string, tableData: any): number => {
|
||||
// str为该列的字段名(传字符串);tableData为该表格的数据源(传变量);
|
||||
|
||||
str = str + '';
|
||||
let columnContent = '';
|
||||
if (!tableData || !tableData.length || tableData.length === 0 || tableData === undefined) {
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
if (!str || !str.length || str.length === 0 || str === undefined) {
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
// 获取该列中最长的数据(内容)
|
||||
let index = 0;
|
||||
@@ -119,52 +129,15 @@ export class TableColumn {
|
||||
}
|
||||
}
|
||||
columnContent = tableData[index][str] + '';
|
||||
const contentWidth: number = TableColumn.getContentWidth(columnContent);
|
||||
// 需要加上表格的内间距等,视情况加
|
||||
const contentWidth: number = getTextWidth(columnContent) + 30;
|
||||
// 获取label的宽度,取较大的宽度
|
||||
const columnWidth: number = TableColumn.getContentWidth(label) + 30;
|
||||
const columnWidth: number = getTextWidth(label) + 60;
|
||||
const flexWidth: number = contentWidth > columnWidth ? contentWidth : columnWidth;
|
||||
return flexWidth + 'px';
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取内容所需要占用的宽度
|
||||
*/
|
||||
static getContentWidth = (content: any): number => {
|
||||
if (!content) {
|
||||
return 50;
|
||||
}
|
||||
// 以下分配的单位长度可根据实际需求进行调整
|
||||
let flexWidth = 0;
|
||||
for (const char of content) {
|
||||
if (flexWidth > 500) {
|
||||
break;
|
||||
}
|
||||
if ((char >= '0' && char <= '9') || (char >= 'a' && char <= 'z')) {
|
||||
// 小写字母、数字字符
|
||||
flexWidth += 9.3;
|
||||
continue;
|
||||
}
|
||||
if (char >= 'A' && char <= 'Z') {
|
||||
flexWidth += 9;
|
||||
continue;
|
||||
}
|
||||
if (char >= '\u4e00' && char <= '\u9fa5') {
|
||||
// 如果是中文字符,为字符分配16个单位宽度
|
||||
flexWidth += 20;
|
||||
} else {
|
||||
// 其他种类字符
|
||||
flexWidth += 8;
|
||||
}
|
||||
}
|
||||
if (flexWidth > 400) {
|
||||
// 设置最大宽度
|
||||
flexWidth = 400;
|
||||
}
|
||||
return flexWidth;
|
||||
return flexWidth > 400 ? 400 : flexWidth;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
export class TableQuery {
|
||||
|
||||
/**
|
||||
|
||||
@@ -311,14 +311,14 @@ const state = reactive({
|
||||
TableQuery.slot("tagPath", "标签", "tagPathSelect"),
|
||||
],
|
||||
columns: [
|
||||
TableColumn.new("tagPath", "标签路径").setSlot("tagPath"),
|
||||
TableColumn.new("tagPath", "标签路径").setSlot("tagPath").setAddWidth(20),
|
||||
TableColumn.new("name", "名称"),
|
||||
TableColumn.new("host", "host:port").setSlot("hostPort"),
|
||||
TableColumn.new("host", "host:port").setSlot("hostPort").setAddWidth(35),
|
||||
TableColumn.new("type", "类型"),
|
||||
TableColumn.new("database", "数据库").setSlot("database").setMinWidth(60),
|
||||
TableColumn.new("database", "数据库").setSlot("database").setMinWidth(70),
|
||||
TableColumn.new("username", "用户名"),
|
||||
TableColumn.new("remark", "备注"),
|
||||
TableColumn.new("action", "操作").setSlot("action").setMinWidth(155).fixedRight(),
|
||||
TableColumn.new("action", "操作").setSlot("action").setMinWidth(175).fixedRight(),
|
||||
],
|
||||
datas: [],
|
||||
total: 0,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* eslint-disable no-unused-vars */
|
||||
import { dbApi } from './api';
|
||||
import { getTextWidth } from '@/common/utils/string';
|
||||
import SqlExecBox from './component/SqlExecBox';
|
||||
|
||||
const dbInstCache: Map<number, DbInst> = new Map();
|
||||
@@ -300,10 +301,8 @@ export class DbInst {
|
||||
* @param flag 标志
|
||||
* @returns 列宽度
|
||||
*/
|
||||
static flexColumnWidth = (str: any, tableData: any, flag = 'equal') => {
|
||||
static flexColumnWidth = (str: any, tableData: any) => {
|
||||
// str为该列的字段名(传字符串);tableData为该表格的数据源(传变量);
|
||||
// flag为可选值,可不传该参数,传参时可选'max'或'equal',默认为'max'
|
||||
// flag为'max'则设置列宽适配该列中最长的内容,flag为'equal'则设置列宽适配该列中第一行内容的长度。
|
||||
str = str + '';
|
||||
let columnContent = '';
|
||||
if (!tableData || !tableData.length || tableData.length === 0 || tableData === undefined) {
|
||||
@@ -312,69 +311,24 @@ export class DbInst {
|
||||
if (!str || !str.length || str.length === 0 || str === undefined) {
|
||||
return;
|
||||
}
|
||||
if (flag === 'equal') {
|
||||
// 获取该列中第一个不为空的数据(内容)
|
||||
for (let i = 0; i < tableData.length; i++) {
|
||||
// 转为字符串后比较
|
||||
if ((tableData[i][str] + '').length > 0) {
|
||||
columnContent = tableData[i][str] + '';
|
||||
break;
|
||||
}
|
||||
// 获取该列中最长的数据(内容)
|
||||
let index = 0;
|
||||
for (let i = 0; i < tableData.length; i++) {
|
||||
if (!tableData[i][str]) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// 获取该列中最长的数据(内容)
|
||||
let index = 0;
|
||||
for (let i = 0; i < tableData.length; i++) {
|
||||
if (tableData[i][str] === null) {
|
||||
return;
|
||||
}
|
||||
const now_temp = tableData[i][str] + '';
|
||||
const max_temp = tableData[index][str] + '';
|
||||
if (now_temp.length > max_temp.length) {
|
||||
index = i;
|
||||
}
|
||||
const now_temp = tableData[i][str] + '';
|
||||
const max_temp = tableData[index][str] + '';
|
||||
if (now_temp.length > max_temp.length) {
|
||||
index = i;
|
||||
}
|
||||
columnContent = tableData[index][str] + '';
|
||||
}
|
||||
const contentWidth: number = DbInst.getContentWidth(columnContent);
|
||||
columnContent = tableData[index][str] + '';
|
||||
const contentWidth: number = getTextWidth(columnContent) + 15;
|
||||
// 获取列名称的长度 加上排序图标长度
|
||||
const columnWidth: number = DbInst.getContentWidth(str) + 43;
|
||||
const columnWidth: number = getTextWidth(str) + 40;
|
||||
const flexWidth: number = contentWidth > columnWidth ? contentWidth : columnWidth;
|
||||
return flexWidth + 'px';
|
||||
};
|
||||
|
||||
/**
|
||||
* 获取内容所需要占用的宽度
|
||||
*/
|
||||
static getContentWidth = (content: any): number => {
|
||||
// 以下分配的单位长度可根据实际需求进行调整
|
||||
let flexWidth = 0;
|
||||
for (const char of content) {
|
||||
if (flexWidth > 500) {
|
||||
break;
|
||||
}
|
||||
if ((char >= '0' && char <= '9') || (char >= 'a' && char <= 'z')) {
|
||||
// 如果是小写字母、数字字符,分配8个单位宽度
|
||||
flexWidth += 8.5;
|
||||
continue;
|
||||
}
|
||||
if (char >= 'A' && char <= 'Z') {
|
||||
flexWidth += 9;
|
||||
continue;
|
||||
}
|
||||
if (char >= '\u4e00' && char <= '\u9fa5') {
|
||||
// 如果是中文字符,为字符分配16个单位宽度
|
||||
flexWidth += 16;
|
||||
} else {
|
||||
// 其他种类字符,为字符分配9个单位宽度
|
||||
flexWidth += 8;
|
||||
}
|
||||
}
|
||||
if (flexWidth > 500) {
|
||||
// 设置最大宽度
|
||||
flexWidth = 500;
|
||||
}
|
||||
return flexWidth;
|
||||
return flexWidth > 500 ? 500 : flexWidth;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -180,11 +180,11 @@ const state = reactive({
|
||||
TableQuery.text("name", "名称"),
|
||||
],
|
||||
columns: [
|
||||
TableColumn.new("tagPath", "标签路径").setSlot("tagPath"),
|
||||
TableColumn.new("tagPath", "标签路径").setSlot("tagPath").setAddWidth(20),
|
||||
TableColumn.new("name", "名称"),
|
||||
TableColumn.new("ipPort", "ip:port").setSlot("ipPort"),
|
||||
TableColumn.new("ipPort", "ip:port").setSlot("ipPort").setAddWidth(35),
|
||||
TableColumn.new("username", "用户名"),
|
||||
TableColumn.new("status", "状态").setSlot("status"),
|
||||
TableColumn.new("status", "状态").setSlot("status").setMinWidth(85),
|
||||
TableColumn.new("remark", "备注"),
|
||||
TableColumn.new("action", "操作").setSlot("action").setMinWidth(235).fixedRight(),
|
||||
],
|
||||
|
||||
@@ -196,7 +196,7 @@ const state = reactive({
|
||||
TableQuery.slot("tagPath", "标签", "tagPathSelect"),
|
||||
],
|
||||
columns: [
|
||||
TableColumn.new("tagPath", "标签路径").setSlot("tagPath"),
|
||||
TableColumn.new("tagPath", "标签路径").setSlot("tagPath").setAddWidth(20),
|
||||
TableColumn.new("name", "名称"),
|
||||
TableColumn.new("uri", "连接uri"),
|
||||
TableColumn.new("createTime", "创建时间").isTime(),
|
||||
|
||||
@@ -165,7 +165,7 @@ const state = reactive({
|
||||
TableQuery.slot("tagPath", "标签", "tagPathSelect"),
|
||||
],
|
||||
columns: [
|
||||
TableColumn.new("tagPath", "标签路径").setSlot("tagPath"),
|
||||
TableColumn.new("tagPath", "标签路径").setSlot("tagPath").setAddWidth(20),
|
||||
TableColumn.new("name", "名称"),
|
||||
TableColumn.new("host", "host:port"),
|
||||
TableColumn.new("mode", "mode"),
|
||||
|
||||
Reference in New Issue
Block a user