feat(YlTable): 新增自定义 tooltip 功能

- 添加 CustomTooptip 组件用于渲染 tooltip 内容
- 在 Index.vue 中集成 tooltip 功能,包括配置项和 formatter
- 优化了表格单元格内容的展示,支持自定义 tooltip 样式和内容
This commit is contained in:
Huangzhe
2025-05-25 21:56:54 +08:00
parent 93b15be8e9
commit 3ef6415a7a
2 changed files with 81 additions and 18 deletions

View File

@@ -1,10 +1,38 @@
<script setup lang="ts">
import { type ColumnStyle } from 'element-plus';
import { showImagePreview } from 'vant';
import { ref } from 'vue';
import { h, ref, type VNode } from 'vue';
import CustomTooptip from './components/Tootips/Index.vue';
type TooltipOptions = {
enterable: boolean;
placement:
| 'top'
| 'bottom'
| 'left'
| 'right'
| 'top-start'
| 'top-end'
| 'bottom-start'
| 'bottom-end'
| 'left-start'
| 'left-end'
| 'right-start'
| 'right-end';
showArrow: boolean;
hideAfter: number;
popperOptions: { strategy: 'fixed' | 'absolute' };
modifiers: {
name: string;
options: {
boundary: string;
padding: number;
};
}[];
};
const data = defineModel<unknown[]>('data', { default: [] });
const props = defineModel<TablePropsType[]>('props');
// 是否只显示单行
const singleLine = defineModel<boolean>('singleLine', { default: false });
const rowStyle = defineModel<ColumnStyle<any>>('rowStyle', {
@@ -12,31 +40,40 @@ const rowStyle = defineModel<ColumnStyle<any>>('rowStyle', {
});
// 显示表格的高度, 默认的高度是 200px
const tableHeight = defineModel<string | number>('height', { default: '300px' });
// 表头样式
const headerStyle = defineModel<ColumnStyle<any>>('headerStyle');
const rounded = defineModel('rounded', { default: true });
const stripeColor = defineModel('stripeColor', { default: 'red' });
// 空数据时的提示文本
const emptyText = defineModel('emptyText', { default: '暂无数据' });
// tooltip options 内容
const tooltipOptions = ref<Partial<TooltipOptions>>({
modifiers: [
{
name: 'preventOverflow',
options: {
boundary: 'viewport',
padding: 8
}
}
]
});
// (data: { row: any; rowIndex: number; }) => string
function setStripeColor(rowData: { row: any; rowIndex: number }): string {
const { rowIndex } = rowData;
return rowIndex % 2 === 0 ? 'even-row' : 'odd-row';
}
function parseTableText(text: string): string {
const imgReg = /<img.*?>/g;
const imgArr = text.match(imgReg);
if (imgArr && imgArr.length > 0) {
return imgArr.join('');
}
return text;
}
// function parseTableText(text: string): string {
// const imgReg = /<img.*?>/g;
// const imgArr = text.match(imgReg);
// if (imgArr && imgArr.length > 0) {
// return imgArr.join('');
// }
// return text;
// }
function handleImageClick(e: Event) {
console.log(e);
if (e.target instanceof HTMLImageElement) {
const imgSrc = e.target.src;
showImagePreview({
@@ -45,15 +82,16 @@ function handleImageClick(e: Event) {
});
}
}
let startX = 0;
let isHorizontal = ref(false);
function handleTouchStart(event) {
let startX = 0;
const isHorizontal = ref(false);
function handleTouchStart(event: TouchEvent) {
startX = event.touches[0].clientX;
isHorizontal.value = false;
}
function handleTouchMove(event) {
function handleTouchMove(event: TouchEvent) {
const deltaX = event.touches[0].clientX - startX;
// 如果是横向滑动,则阻止冒泡
@@ -62,6 +100,12 @@ function handleTouchMove(event) {
event.stopPropagation(); // 阻止事件冒泡到 van-swipe
}
}
function tooptipFormatter(data: { row: any; column: any; cellValue: any }): VNode {
return h(CustomTooptip, {
content: data
});
}
</script>
<template>
@@ -72,6 +116,8 @@ function handleTouchMove(event) {
@touchmove="handleTouchMove"
>
<el-table
:tooltip-options="tooltipOptions"
:tooltip-formatter="tooptipFormatter"
:max-height="tableHeight"
:header-cell-style="headerStyle || { background: '#f2f8ee' }"
:row-class-name="setStripeColor"
@@ -90,8 +136,8 @@ function handleTouchMove(event) {
<slot name="column-default" :scope="scope">
<div
class="table-view-html"
@click.stop="handleImageClick"
v-html="scope.row[item.prop]"
@click.native="handleImageClick"
></div>
</slot>
</template>

View File

@@ -0,0 +1,17 @@
<script setup lang="ts">
const content = defineModel<{ row: any; column: any; cellValue: any }>('content');
</script>
<template>
<div class="tooltip-content">
<span v-html="content?.row?.logic_text"></span>
</div>
</template>
<style lang="scss" scoped>
.tooltip-content {
width: 90vw;
max-height: 45vh;
overflow: scroll;
}
</style>