"ant-design-vue": "^1.78"
table表格customRender的使用
使用customRender指定渲染内容
colums: [
{
title: '类型',
dataIndex: 'type',
customRender: (text, record) => {
console.log(record);
if (text === 0) {
return '客户1'
} else if (text === 1) {
return '客户2',
} else if (text === 2) {
return '客户3'
}
}
}
]
注意:text参数为当前行的值;record参数为当前行数据
使用customRender引入插槽
scopedSlots: { customRender: 'action' }
在slot中使用 a-tooltip(文字提示)
插槽代码。文本溢出显示省略号。
<template slot="tooltipSlot" slot-scope="text">
<a-tooltip placement="top" :title="text">
<div
style="width: 350px; overflow: hidden; text-overflow: ellipsis"
>{{ text }}</div>
</a-tooltip>
</template>
需要注意的是需要设置宽度,否则不能实现居中
{
title: '诉求内容',
align: "center",
width: 350, // 对于tooltipSlot需要设置宽度才能居中
dataIndex: 'sjms',
scopedSlots: { customRender: 'tooltipSlot' }
},
"ant-design-vue": "^3.2.20"
customRow设置行属性Function(record, index)
鼠标右键事件和关闭事件,双击事件
const customRow = (record, index) => {
return {
// 鼠标右键
onContextmenu: (e) => {
e.preventDefault();
document.body.addEventListener("click", cancelClick);
},
// 鼠标双击
ondblclick: (e) => {
},
};
};
cancelClick关闭事件
const cancelClick = () => {
document.body.removeEventListener("click", cancelClick);
};
拖拽事件
拖拽分为同表格拖拽和跨表格拖拽。官网推荐的Surely Table不付费会有水印,且需要导入新的组件库,功能也不完善。官网中所给出的案例只支持同表格拖拽、单行拖拽。
copy网上案例、加工实现多行跨表格移动、单行同表格排序
拖拽的数据定义在pinia中,src/store/draggable.js
import {
defineStore
} from 'pinia'
export const draggableRecord = defineStore('draggableRecord', {
state: () => {
return {
record: [],
source: ''
}
},
actions: {
init() {
this.record = []
this.source = ''
},
draggable(record, source) {
this.record = record
this.source = source
}
},
})
表格组件 videoList.vue
<a-table
:columns="columns"
:data-source="data"
:pagination="false"
:row-selection="rowSelection"
:customRow="customRow"
>
<script setup>
import { draggableRecord } from "/@/store/draggable";
const props = defineProps({
// 组件渲染位置 top: 视频列表, import: 导入视频列表
which: {
type: String,
default: "top",
required: true,
}
})
const emit = defineEmits(["diff-source", "same-source"]);
const draggableStore = draggableRecord();
let change1 = null; // 源数据序号
let change2 = null; // 目标数据序号
const customRow = (record, index) => {
return {
// 拖拽------------------------------------------------start
onMouseenter: (event) => {
// 兼容IE
var ev = event || window.event;
ev.target.draggable = true; // 让你要拖动的行可以拖动,默认不可以
},
// 开始拖拽
onDragstart: (event) => {
// 兼容IE
var ev = event || window.event;
// 阻止冒泡
ev.stopPropagation();
// 得到源目标数据序号
change1 = index;
// 判断是否为多选拖拽
Object.keys(rowSelect.value).length > 0
? draggableStore.draggable(rowSelect.value, props.which)
: draggableStore.draggable([record], props.which);
// console.log(record, index, "上面source");
},
// 拖动元素经过的元素
onDragover: (event) => {
// 兼容 IE
var ev = event || window.event;
// 阻止默认行为
ev.preventDefault();
},
// 鼠标松开
onDrop: (event) => {
// 兼容IE
var ev = event || window.event;
// 阻止冒泡
ev.stopPropagation();
// 得到目标数据序号
change2 = index;
// 根据数据来源和当前位置,计算是跨表格还是本表格
draggableStore.source === props.which
? rowSelect.value.length > 0 // 多选不支持排序
? ""
: emit("same-source", {
change1,
change2,
})
: emit("diff-source", { index, record: draggableStore.record });
// console.log(data, index, "上面的target");
draggableStore.init(); // 将拖拽数据初始化
},
// 拖拽------------------------------------------------end
};
};
</script>
父组件importVideo.vue
<video-list
which="import"
:data="importData"
:columns="videoColums"
@same-source="onSameSource"
@diff-source="onDiffSource"
></video-list>
<script setup>
const onDiffSource = (mess) => {
// console.log("onDiffSource");
importData.splice(mess.index, 0, ...mess.record);
};
const onSameSource = (mess) => {
// console.log("onSameSource");
const move = importData[mess.change1];
importData.splice(mess.change1, 1);
importData.splice(mess.change2, 0, move);
};
</script>
getPopupContainer解决悬浮窗遮挡问题
ant.design/components/… 给出的定义
弹出框(Select, Tooltip, Menu 等等)渲染父节点,默认渲染到 body 上。
如果你使用的 a-select、a-popover、a-tooltip、a-menu等组件都可以直接使用此属性
<a-select
v-model="title"
show-search
:options="filterList"
:getPopupContainer="getPopupContainer"
></a-select>
//js
// 解决antdv组件被覆盖的问题
const getPopupContainer = (node) => {
return document.body
};
效果为:
官网给出的写法:
getPopupContainer={triggerNode => triggerNode.parentElement || document.body}
有些场景无法解决问题,见下【customHeaderCell设置头部单元格属性,Select】
customHeaderCell设置头部单元格属性,Select
如果是分页的话,参照官网案例【自定义筛选菜单】章节
但是如果是滚动形式就会出现一些bug
<a-table
class="ant-table-striped"
:columns="columns"
:data-source="data"
:pagination="false"
:scroll="{x:1000, y:410}"
>
<template #headerCell="{title, column }">
<a-select
v-model="column.title"
show-search
:placeholder="title"
:style="{width: column.filterType === 'select' ? '100%': '70%'}"
:options="filterList[title]"
:filter-option="filterOption"
:getPopupContainer="getPopupContainer"
></a-select>
</template>
</a-table>
bug
当设置 :scroll="{x:1000, y:410}"属性后,ant-table-header就会添加overflow: hidden;,影响下拉等悬浮层的显示
如果使用css的方式解决问题,表头横向就无法实现滚动,而是溢出显示。
:deep(.ant-table-header) {
overflow: visible
}
并且不能这样写:
:deep(.ant-table-header) {
overflow-y: visible;
overflow-x: hidden;
}
只能使用getPopupContainer
不能使用官网给出的return triggerNode.parentElement,这个return不能解决这个问题
const getPopupContainer = (node) => {
return document.body
};
ant-table-body添加滚轮事件
直接给 a-table 使用 ref 无法获取dom,所以在外层添加父元素
<div ref="ant_table_box" class="table-box" :class="scrollHidden ? 'no-srcoll-y': ''">
<a-table
class="ant-table-striped"
:columns="columns"
:data-source="data"
:pagination="false"
:scroll="tableProps.scroll"
:customRow="customRow"
>
</div>
// js
const tableProps = reactive({
scroll: {
x: 988,
y: 410,
},
});
const ant_table_box = ref(null);
});
const scrollHidden = computed(() => {
if (ant_table_box.value != null) {
const ant_table_body_dom =
ant_table_box.value.querySelector(".ant-table-body");
if (ant_table_body_dom.offsetHeight > tableProps.scroll.y) {
return false;
} else {
return true;
}
} else {
return false;
}
});
onMounted(() => {
if (ant_table_box.value) {
const ant_table_body_dom =
ant_table_box.value.querySelector(".ant-table-body");
ant_table_body_dom?.addEventListener("scroll", (event) => {
// 计算滚动到底部的条件
// -1 防止误差
const isBottom =
ant_table_body_dom.clientHeight +
parseInt(ant_table_body_dom.scrollTop.toFixed(0)) ===
ant_table_body_dom.scrollHeight ||
ant_table_body_dom.clientHeight +
parseInt(ant_table_body_dom.scrollTop.toFixed(0)) -
1 ===
ant_table_body_dom.scrollHeight;
if (isBottom) {
// 滚动到底部时执行你的逻辑
const newData = Object.assign([], props.data.slice(0, 10));
props.data.push(...newData);
// console.log("改变后的table数据", props.data);
}
});
}
});
// css
<style scoped lang="less">
:deep(.ant-table-body) {
&::-webkit-scrollbar {
border-radius: 5px;
height: 8px;
width: 5px;
background-color: #a09d9d;
}
&::-webkit-scrollbar-thumb {
width: 10px;
border-radius: 10px;
// background-color: rgba(192, 39, 39, 0);
background: #24222294;
}
}
.no-srcoll-y {
:deep(.ant-table-body) {
overflow: auto !important;
}
}
.table-box {
width: 100%;
position: relative;
border-radius: 4px;
border: 1px solid rgb(63, 61, 61);
overflow: hidden;
}
</style>