✨(component): 新增 span-method 属性, 支持行列合并
This commit is contained in:
parent
2a95b7a3e4
commit
0f4144fafc
@ -31,6 +31,7 @@ export interface LayTableRowProps {
|
|||||||
rowStyle: string | Function;
|
rowStyle: string | Function;
|
||||||
id: string;
|
id: string;
|
||||||
data: any;
|
data: any;
|
||||||
|
spanMethod: Function;
|
||||||
}
|
}
|
||||||
|
|
||||||
const slot = useSlots();
|
const slot = useSlots();
|
||||||
@ -188,6 +189,37 @@ const renderFixedClassName = (column: any, columnIndex: number) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const spanMethodAttr = (
|
||||||
|
row: any,
|
||||||
|
column: any,
|
||||||
|
rowIndex: number,
|
||||||
|
columnIndex: number) => {
|
||||||
|
|
||||||
|
const attrs = props.spanMethod(row, column, rowIndex, columnIndex);
|
||||||
|
if(attrs instanceof Array) {
|
||||||
|
return {rowspan: attrs[0], colspan: attrs[1]}
|
||||||
|
} else if(attrs instanceof Object) {
|
||||||
|
return attrs;
|
||||||
|
} else {
|
||||||
|
return {rowspan: 1, colspan: 1}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const isAutoShow = (
|
||||||
|
row: any,
|
||||||
|
column: any,
|
||||||
|
rowIndex: number,
|
||||||
|
columnIndex: number) => {
|
||||||
|
|
||||||
|
const attrs = spanMethodAttr(row, column, rowIndex, columnIndex);
|
||||||
|
if(attrs.colspan == 0 && attrs.rowspan == 0) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@ -203,6 +235,9 @@ const renderFixedClassName = (column: any, columnIndex: number) => {
|
|||||||
<template v-if="column.type == 'radio'">
|
<template v-if="column.type == 'radio'">
|
||||||
<td
|
<td
|
||||||
class="layui-table-cell layui-table-cell-radio"
|
class="layui-table-cell layui-table-cell-radio"
|
||||||
|
v-if="isAutoShow(data, column, index, columnIndex)"
|
||||||
|
:colspan="spanMethodAttr(data, column, index, columnIndex).colspan"
|
||||||
|
:rowspan="spanMethodAttr(data, column, index, columnIndex).rowspan"
|
||||||
:style="[
|
:style="[
|
||||||
{
|
{
|
||||||
textAlign: column.align,
|
textAlign: column.align,
|
||||||
@ -249,6 +284,9 @@ const renderFixedClassName = (column: any, columnIndex: number) => {
|
|||||||
<template v-if="column.type == 'checkbox'">
|
<template v-if="column.type == 'checkbox'">
|
||||||
<td
|
<td
|
||||||
class="layui-table-cell layui-table-cell-checkbox"
|
class="layui-table-cell layui-table-cell-checkbox"
|
||||||
|
v-if="isAutoShow(data, column, index, columnIndex)"
|
||||||
|
:colspan="spanMethodAttr(data, column, index, columnIndex).colspan"
|
||||||
|
:rowspan="spanMethodAttr(data, column, index, columnIndex).rowspan"
|
||||||
:style="[
|
:style="[
|
||||||
{
|
{
|
||||||
textAlign: column.align,
|
textAlign: column.align,
|
||||||
@ -299,6 +337,9 @@ const renderFixedClassName = (column: any, columnIndex: number) => {
|
|||||||
<template v-if="column.type == 'number'">
|
<template v-if="column.type == 'number'">
|
||||||
<td
|
<td
|
||||||
class="layui-table-cell layui-table-cell-number"
|
class="layui-table-cell layui-table-cell-number"
|
||||||
|
v-if="isAutoShow(data, column, index, columnIndex)"
|
||||||
|
:colspan="spanMethodAttr(data, column, index, columnIndex).colspan"
|
||||||
|
:rowspan="spanMethodAttr(data, column, index, columnIndex).rowspan"
|
||||||
:style="[
|
:style="[
|
||||||
{
|
{
|
||||||
textAlign: column.align,
|
textAlign: column.align,
|
||||||
@ -345,6 +386,9 @@ const renderFixedClassName = (column: any, columnIndex: number) => {
|
|||||||
<template v-if="column.customSlot">
|
<template v-if="column.customSlot">
|
||||||
<td
|
<td
|
||||||
class="layui-table-cell"
|
class="layui-table-cell"
|
||||||
|
v-if="isAutoShow(data, column, index, columnIndex)"
|
||||||
|
:colspan="spanMethodAttr(data, column, index, columnIndex).colspan"
|
||||||
|
:rowspan="spanMethodAttr(data, column, index, columnIndex).rowspan"
|
||||||
:style="[
|
:style="[
|
||||||
{
|
{
|
||||||
textAlign: column.align,
|
textAlign: column.align,
|
||||||
@ -399,6 +443,9 @@ const renderFixedClassName = (column: any, columnIndex: number) => {
|
|||||||
<template v-if="column.key in data">
|
<template v-if="column.key in data">
|
||||||
<td
|
<td
|
||||||
class="layui-table-cell"
|
class="layui-table-cell"
|
||||||
|
v-if="isAutoShow(data, column, index, columnIndex)"
|
||||||
|
:colspan="spanMethodAttr(data, column, index, columnIndex).colspan"
|
||||||
|
:rowspan="spanMethodAttr(data, column, index, columnIndex).rowspan"
|
||||||
:style="[
|
:style="[
|
||||||
{
|
{
|
||||||
textAlign: column.align,
|
textAlign: column.align,
|
||||||
@ -479,9 +526,10 @@ const renderFixedClassName = (column: any, columnIndex: number) => {
|
|||||||
:cellClassName="cellClassName"
|
:cellClassName="cellClassName"
|
||||||
:rowStyle="rowStyle"
|
:rowStyle="rowStyle"
|
||||||
:rowClassName="rowClassName"
|
:rowClassName="rowClassName"
|
||||||
|
:spanMethod="spanMethod"
|
||||||
@row="rowClick"
|
@row="rowClick"
|
||||||
@row-double="rowDoubleClick"
|
@row-double="rowDoubleClick"
|
||||||
@contextmenu="contextmenu"
|
@row-contextmenu="rowContextmenu"
|
||||||
v-model:selectedKeys="tableSelectedKeys"
|
v-model:selectedKeys="tableSelectedKeys"
|
||||||
v-model:selectedKey="tableSelectedKey"
|
v-model:selectedKey="tableSelectedKey"
|
||||||
>
|
>
|
||||||
|
@ -45,6 +45,7 @@ export interface LayTableProps {
|
|||||||
cellClassName?: string | Function;
|
cellClassName?: string | Function;
|
||||||
rowStyle?: string | Function;
|
rowStyle?: string | Function;
|
||||||
cellStyle?: string | Function;
|
cellStyle?: string | Function;
|
||||||
|
spanMethod?: Function;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<LayTableProps>(), {
|
const props = withDefaults(defineProps<LayTableProps>(), {
|
||||||
@ -61,6 +62,7 @@ const props = withDefaults(defineProps<LayTableProps>(), {
|
|||||||
expandIndex: 0,
|
expandIndex: 0,
|
||||||
rowStyle: "",
|
rowStyle: "",
|
||||||
cellStyle: "",
|
cellStyle: "",
|
||||||
|
spanMethod: () => {}
|
||||||
});
|
});
|
||||||
|
|
||||||
const tableId = uuidv4();
|
const tableId = uuidv4();
|
||||||
@ -285,10 +287,7 @@ const getFixedColumn = () => {
|
|||||||
hasr.value = true;
|
hasr.value = true;
|
||||||
} else {
|
} else {
|
||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
if (
|
if (tableBody.value?.scrollLeft + tableBody.value?.offsetWidth + 2 >tableBody.value?.scrollWidth) {
|
||||||
tableBody.value?.scrollLeft + tableBody.value?.offsetWidth + 2 >
|
|
||||||
tableBody.value?.scrollWidth
|
|
||||||
) {
|
|
||||||
hasl.value = true;
|
hasl.value = true;
|
||||||
hasr.value = false;
|
hasr.value = false;
|
||||||
} else {
|
} else {
|
||||||
@ -578,6 +577,7 @@ const renderTotalRowCell = (column: any) => {
|
|||||||
:cellClassName="cellClassName"
|
:cellClassName="cellClassName"
|
||||||
:rowStyle="rowStyle"
|
:rowStyle="rowStyle"
|
||||||
:rowClassName="rowClassName"
|
:rowClassName="rowClassName"
|
||||||
|
:spanMethod="spanMethod"
|
||||||
@row="rowClick"
|
@row="rowClick"
|
||||||
@row-double="rowDoubleClick"
|
@row-double="rowDoubleClick"
|
||||||
@row-contextmenu="rowContextmenu"
|
@row-contextmenu="rowContextmenu"
|
||||||
|
@ -811,6 +811,82 @@ export default {
|
|||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
::: title 合并行列
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: demo 通过 `columns` 配置 `type:'radio'` 开启单选列。
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<lay-table :columns="columns24" :data-source="dataSource24" v-model:selected-key="selectedKey24" :spanMethod="spanMethod24"></lay-table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
|
||||||
|
const columns24 = [
|
||||||
|
{
|
||||||
|
title:"账户",
|
||||||
|
width:"200px",
|
||||||
|
key:"username"
|
||||||
|
},{
|
||||||
|
title:"密码",
|
||||||
|
width: "300px",
|
||||||
|
key:"password"
|
||||||
|
},{
|
||||||
|
title:"性别",
|
||||||
|
key:"sex"
|
||||||
|
},{
|
||||||
|
title:"年龄",
|
||||||
|
width: "300px",
|
||||||
|
key:"age"
|
||||||
|
},{
|
||||||
|
title:"备注",
|
||||||
|
width: "180px",
|
||||||
|
key:"remark",
|
||||||
|
ellipsisTooltip: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const selectedKey24 = ref("2");
|
||||||
|
|
||||||
|
const dataSource24 = [
|
||||||
|
{id:"1",username:"root", password:"root",sex:"男", age:"18", remark: 'layui - vue(谐音:类 UI) '},
|
||||||
|
{id:"2",username:"root", password:"root",sex:"男", age:"18", remark: 'layui - vue(谐音:类 UI) '},
|
||||||
|
{id:"3",username:"woow", password:"woow",sex:"男", age:"20", remark: 'layui - vue(谐音:类 UI) '},
|
||||||
|
{id:"4",username:"woow", password:"woow",sex:"男", age:"20", remark: 'layui - vue(谐音:类 UI) '},
|
||||||
|
{id:"5",username:"woow", password:"woow",sex:"男", age:"20", remark: 'layui - vue(谐音:类 UI) '}
|
||||||
|
]
|
||||||
|
|
||||||
|
const spanMethod24 = (
|
||||||
|
row,
|
||||||
|
column,
|
||||||
|
rowIndex,
|
||||||
|
columnIndex,
|
||||||
|
) => {
|
||||||
|
if (rowIndex % 2 === 0) {
|
||||||
|
if (columnIndex === 0) {
|
||||||
|
return [1, 2]
|
||||||
|
} else if (columnIndex === 1) {
|
||||||
|
return [0, 0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
columns24,
|
||||||
|
dataSource24,
|
||||||
|
spanMethod24,
|
||||||
|
selectedKey24,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
::: title 暂无数据
|
::: title 暂无数据
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user