✨(table): 新增 cellStyle cellClassName rowStyle rowClassName 属性, 用于自定义单元格样式
This commit is contained in:
parent
46d5533e45
commit
de8746e02d
@ -12,6 +12,7 @@ import LayDropdown from "../dropdown/index.vue";
|
|||||||
import LayTooltip from "../tooltip/index.vue";
|
import LayTooltip from "../tooltip/index.vue";
|
||||||
|
|
||||||
export interface LayTableRowProps {
|
export interface LayTableRowProps {
|
||||||
|
index: number;
|
||||||
indentSize: number;
|
indentSize: number;
|
||||||
currentIndentSize: number;
|
currentIndentSize: number;
|
||||||
expandSpace: boolean;
|
expandSpace: boolean;
|
||||||
@ -20,6 +21,10 @@ export interface LayTableRowProps {
|
|||||||
childrenColumnName?: string;
|
childrenColumnName?: string;
|
||||||
columns: Recordable[];
|
columns: Recordable[];
|
||||||
checkbox?: boolean;
|
checkbox?: boolean;
|
||||||
|
cellClassName: string | Function;
|
||||||
|
cellStyle: string | Function;
|
||||||
|
rowClassName: string | Function;
|
||||||
|
rowStyle: string | Function;
|
||||||
id: string;
|
id: string;
|
||||||
data: any;
|
data: any;
|
||||||
}
|
}
|
||||||
@ -35,6 +40,8 @@ const emit = defineEmits([
|
|||||||
const props = withDefaults(defineProps<LayTableRowProps>(), {
|
const props = withDefaults(defineProps<LayTableRowProps>(), {
|
||||||
checkbox: false,
|
checkbox: false,
|
||||||
childrenColumnName: "children",
|
childrenColumnName: "children",
|
||||||
|
cellStyle: "",
|
||||||
|
cellClassName: ""
|
||||||
});
|
});
|
||||||
|
|
||||||
const tableSelectedKeys: WritableComputedRef<Recordable[]> = computed({
|
const tableSelectedKeys: WritableComputedRef<Recordable[]> = computed({
|
||||||
@ -75,11 +82,41 @@ const handleExpand = () => {
|
|||||||
isExpand.value = !isExpand.value;
|
isExpand.value = !isExpand.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const renderCellStyle = (row: any, column: any, rowIndex: number, columnIndex: number) => {
|
||||||
|
if(typeof props.cellStyle === 'string') {
|
||||||
|
return props.cellStyle;
|
||||||
|
}
|
||||||
|
return props.cellStyle(row, column, rowIndex, columnIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderCellClassName = (row: any, column: any, rowIndex: number, columnIndex: number) => {
|
||||||
|
if(typeof props.cellClassName === 'string') {
|
||||||
|
return props.cellClassName;
|
||||||
|
}
|
||||||
|
return props.cellClassName(row, column, rowIndex, columnIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderRowStyle = (data: any, index: number) => {
|
||||||
|
if(typeof props.rowStyle === 'string') {
|
||||||
|
return props.rowStyle;
|
||||||
|
}
|
||||||
|
return props.rowStyle(data, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
const renderRowClassName = (data: any, index: number) => {
|
||||||
|
if(typeof props.rowClassName === 'string') {
|
||||||
|
return props.rowClassName;
|
||||||
|
}
|
||||||
|
return props.rowClassName(data, index);
|
||||||
|
}
|
||||||
|
|
||||||
const childrenIndentSize = props.currentIndentSize + props.indentSize;
|
const childrenIndentSize = props.currentIndentSize + props.indentSize;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<tr
|
<tr
|
||||||
|
:style="[renderRowStyle(data, index)]"
|
||||||
|
:class="[renderRowClassName(data, index)]"
|
||||||
@click.stop="rowClick(data, $event)"
|
@click.stop="rowClick(data, $event)"
|
||||||
@dblclick.stop="rowDoubleClick(data, $event)"
|
@dblclick.stop="rowDoubleClick(data, $event)"
|
||||||
@contextmenu.stop="contextmenu(data, $event)"
|
@contextmenu.stop="contextmenu(data, $event)"
|
||||||
@ -96,21 +133,22 @@ const childrenIndentSize = props.currentIndentSize + props.indentSize;
|
|||||||
</td>
|
</td>
|
||||||
|
|
||||||
<!-- 数据列 -->
|
<!-- 数据列 -->
|
||||||
<template v-for="(column, index) in columns" :key="column">
|
<template v-for="(column, columnIndex) in columns" :key="columnIndex">
|
||||||
<!-- 展示否 -->
|
<!-- 展示否 -->
|
||||||
<template v-if="tableColumnKeys.includes(column.key)">
|
<template v-if="tableColumnKeys.includes(column.key)">
|
||||||
<!-- 插槽列 -->
|
<!-- 插槽列 -->
|
||||||
<template v-if="column.customSlot">
|
<template v-if="column.customSlot">
|
||||||
<td
|
<td
|
||||||
class="layui-table-cell"
|
class="layui-table-cell"
|
||||||
:style="{
|
:style="[{
|
||||||
textAlign: column.align,
|
textAlign: column.align,
|
||||||
whiteSpace: column.ellipsisTooltip ? 'nowrap' : 'normal',
|
whiteSpace: column.ellipsisTooltip ? 'nowrap' : 'normal',
|
||||||
}"
|
}, renderCellStyle(data, column, index, columnIndex)]"
|
||||||
|
:class="[renderCellClassName(data, column, index, columnIndex)]"
|
||||||
>
|
>
|
||||||
<!-- 树表占位与缩进 -->
|
<!-- 树表占位与缩进 -->
|
||||||
<span
|
<span
|
||||||
v-if="expandSpace && index === 0"
|
v-if="expandSpace && columnIndex === 0"
|
||||||
:style="{ 'margin-right': currentIndentSize + 'px' }"
|
:style="{ 'margin-right': currentIndentSize + 'px' }"
|
||||||
></span>
|
></span>
|
||||||
|
|
||||||
@ -119,13 +157,13 @@ const childrenIndentSize = props.currentIndentSize + props.indentSize;
|
|||||||
expandSpace &&
|
expandSpace &&
|
||||||
!data[childrenColumnName] &&
|
!data[childrenColumnName] &&
|
||||||
!slot.expand &&
|
!slot.expand &&
|
||||||
index === 0
|
columnIndex === 0
|
||||||
"
|
"
|
||||||
class="layui-table-cell-expand-icon-spaced"
|
class="layui-table-cell-expand-icon-spaced"
|
||||||
></span>
|
></span>
|
||||||
|
|
||||||
<lay-icon
|
<lay-icon
|
||||||
v-if="(slot.expand || data[childrenColumnName]) && index === 0"
|
v-if="(slot.expand || data[childrenColumnName]) && columnIndex === 0"
|
||||||
class="layui-table-cell-expand-icon"
|
class="layui-table-cell-expand-icon"
|
||||||
:type="expandIconType"
|
:type="expandIconType"
|
||||||
@click="handleExpand"
|
@click="handleExpand"
|
||||||
@ -147,14 +185,15 @@ const childrenIndentSize = props.currentIndentSize + props.indentSize;
|
|||||||
<template v-if="column.key in data">
|
<template v-if="column.key in data">
|
||||||
<td
|
<td
|
||||||
class="layui-table-cell"
|
class="layui-table-cell"
|
||||||
:style="{
|
:style="[{
|
||||||
textAlign: column.align,
|
textAlign: column.align,
|
||||||
whiteSpace: column.ellipsisTooltip ? 'nowrap' : 'normal',
|
whiteSpace: column.ellipsisTooltip ? 'nowrap' : 'normal',
|
||||||
}"
|
}, renderCellStyle(data, column, index, columnIndex)]"
|
||||||
|
:class="[renderCellClassName(data, column, index, columnIndex)]"
|
||||||
>
|
>
|
||||||
<!-- 树表占位与缩进 -->
|
<!-- 树表占位与缩进 -->
|
||||||
<span
|
<span
|
||||||
v-if="expandSpace && index === 0"
|
v-if="expandSpace && columnIndex === 0"
|
||||||
:style="{ 'margin-right': currentIndentSize + 'px' }"
|
:style="{ 'margin-right': currentIndentSize + 'px' }"
|
||||||
></span>
|
></span>
|
||||||
|
|
||||||
@ -163,13 +202,13 @@ const childrenIndentSize = props.currentIndentSize + props.indentSize;
|
|||||||
expandSpace &&
|
expandSpace &&
|
||||||
!data[childrenColumnName] &&
|
!data[childrenColumnName] &&
|
||||||
!slot.expand &&
|
!slot.expand &&
|
||||||
index === 0
|
columnIndex === 0
|
||||||
"
|
"
|
||||||
class="layui-table-cell-expand-icon-spaced"
|
class="layui-table-cell-expand-icon-spaced"
|
||||||
></span>
|
></span>
|
||||||
|
|
||||||
<lay-icon
|
<lay-icon
|
||||||
v-if="(slot.expand || data[childrenColumnName]) && index === 0"
|
v-if="(slot.expand || data[childrenColumnName]) && columnIndex === 0"
|
||||||
class="layui-table-cell-expand-icon"
|
class="layui-table-cell-expand-icon"
|
||||||
:type="expandIconType"
|
:type="expandIconType"
|
||||||
@click="handleExpand"
|
@click="handleExpand"
|
||||||
@ -198,11 +237,12 @@ const childrenIndentSize = props.currentIndentSize + props.indentSize;
|
|||||||
<!-- 树形结构 -->
|
<!-- 树形结构 -->
|
||||||
<template v-if="data[childrenColumnName] && isExpand">
|
<template v-if="data[childrenColumnName] && isExpand">
|
||||||
<template
|
<template
|
||||||
v-for="(children, index) in data[childrenColumnName]"
|
v-for="(children, childrenIndex) in data[childrenColumnName]"
|
||||||
:key="index"
|
:key="childrenIndex"
|
||||||
>
|
>
|
||||||
<table-row
|
<table-row
|
||||||
:id="id"
|
:id="id"
|
||||||
|
:index="childrenIndex"
|
||||||
:data="children"
|
:data="children"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:indent-size="indentSize"
|
:indent-size="indentSize"
|
||||||
@ -210,6 +250,10 @@ const childrenIndentSize = props.currentIndentSize + props.indentSize;
|
|||||||
:checkbox="checkbox"
|
:checkbox="checkbox"
|
||||||
:tableColumnKeys="tableColumnKeys"
|
:tableColumnKeys="tableColumnKeys"
|
||||||
:expandSpace="expandSpace"
|
:expandSpace="expandSpace"
|
||||||
|
:cellStyle="cellStyle"
|
||||||
|
:cellClassName="cellClassName"
|
||||||
|
:rowStyle="rowStyle"
|
||||||
|
:rowClassName="rowClassName"
|
||||||
@row="rowClick"
|
@row="rowClick"
|
||||||
@row-double="rowDoubleClick"
|
@row-double="rowDoubleClick"
|
||||||
@contextmenu="contextmenu"
|
@contextmenu="contextmenu"
|
||||||
|
@ -30,6 +30,10 @@ export interface LayTableProps {
|
|||||||
height?: number;
|
height?: number;
|
||||||
maxHeight?: string;
|
maxHeight?: string;
|
||||||
even?: boolean;
|
even?: boolean;
|
||||||
|
rowClassName?: string | Function;
|
||||||
|
cellClassName?: string | Function;
|
||||||
|
rowStyle?: string | Function;
|
||||||
|
cellStyle?: string | Function;
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<LayTableProps>(), {
|
const props = withDefaults(defineProps<LayTableProps>(), {
|
||||||
@ -41,6 +45,10 @@ const props = withDefaults(defineProps<LayTableProps>(), {
|
|||||||
selectedKeys: () => [],
|
selectedKeys: () => [],
|
||||||
maxHeight: "auto",
|
maxHeight: "auto",
|
||||||
even: false,
|
even: false,
|
||||||
|
rowClassName: "",
|
||||||
|
cellClassName: "",
|
||||||
|
rowStyle: "",
|
||||||
|
cellStyle: "",
|
||||||
});
|
});
|
||||||
|
|
||||||
const tableId = uuidv4();
|
const tableId = uuidv4();
|
||||||
@ -384,9 +392,10 @@ props.dataSource.map((value: any) => {
|
|||||||
</colgroup>
|
</colgroup>
|
||||||
<tbody>
|
<tbody>
|
||||||
<!-- 渲染 -->
|
<!-- 渲染 -->
|
||||||
<template v-for="data in tableDataSource" :key="data">
|
<template v-for="(data, index) in tableDataSource" :key="data">
|
||||||
<table-row
|
<table-row
|
||||||
:id="id"
|
:id="id"
|
||||||
|
:index="index"
|
||||||
:data="data"
|
:data="data"
|
||||||
:columns="columns"
|
:columns="columns"
|
||||||
:checkbox="checkbox"
|
:checkbox="checkbox"
|
||||||
@ -394,6 +403,10 @@ props.dataSource.map((value: any) => {
|
|||||||
:currentIndentSize="currentIndentSize"
|
:currentIndentSize="currentIndentSize"
|
||||||
:tableColumnKeys="tableColumnKeys"
|
:tableColumnKeys="tableColumnKeys"
|
||||||
:expandSpace="childrenExpandSpace"
|
:expandSpace="childrenExpandSpace"
|
||||||
|
:cellStyle="cellStyle"
|
||||||
|
:cellClassName="cellClassName"
|
||||||
|
:rowStyle="rowStyle"
|
||||||
|
:rowClassName="rowClassName"
|
||||||
@row="rowClick"
|
@row="rowClick"
|
||||||
@row-double="rowDoubleClick"
|
@row-double="rowDoubleClick"
|
||||||
@contextmenu="contextmenu"
|
@contextmenu="contextmenu"
|
||||||
|
@ -530,6 +530,74 @@ export default {
|
|||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
|
::: title 定义样式
|
||||||
|
:::
|
||||||
|
|
||||||
|
::: demo 通过 `cellStyle` `rowStyle` `cellClassName` `rowClassName` 属性, 自定义单元格样式。
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<lay-table :columns="columns1" :dataSource="dataSource1" :cellStyle="cellStyle" :rowStyle="rowStyle"></lay-table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
setup() {
|
||||||
|
|
||||||
|
const columns1 = [
|
||||||
|
{
|
||||||
|
title:"账户",
|
||||||
|
width:"200px",
|
||||||
|
key:"username"
|
||||||
|
},{
|
||||||
|
title:"密码",
|
||||||
|
width: "180px",
|
||||||
|
key:"password"
|
||||||
|
},{
|
||||||
|
title:"年龄",
|
||||||
|
width: "180px",
|
||||||
|
key:"age"
|
||||||
|
},{
|
||||||
|
title:"备注",
|
||||||
|
width: "180px",
|
||||||
|
key:"remark",
|
||||||
|
ellipsisTooltip: true,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
const dataSource1 = [
|
||||||
|
{username:"root", password:"root", age:"18", remark: 'layui - vue(谐音:类 UI) '},
|
||||||
|
{username:"root", password:"root", age:"18", remark: 'layui - vue(谐音:类 UI) '},
|
||||||
|
{username:"woow", password:"woow", age:"20", remark: 'layui - vue(谐音:类 UI) '},
|
||||||
|
{username:"woow", password:"woow", age:"20", remark: 'layui - vue(谐音:类 UI) '},
|
||||||
|
{username:"woow", password:"woow", age:"20", remark: 'layui - vue(谐音:类 UI) '}
|
||||||
|
]
|
||||||
|
|
||||||
|
const cellStyle = function(row, column, rowIndex, columnIndex) {
|
||||||
|
if(columnIndex % 2 == 0) {
|
||||||
|
return 'color:red';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const rowStyle = function(row, rowIndex) {
|
||||||
|
if(rowIndex % 2 == 0) {
|
||||||
|
return 'color:blue';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
columns1,
|
||||||
|
dataSource1,
|
||||||
|
cellStyle,
|
||||||
|
rowStyle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
:::
|
||||||
|
|
||||||
::: title Table 属性
|
::: title Table 属性
|
||||||
:::
|
:::
|
||||||
|
|
||||||
@ -549,6 +617,11 @@ export default {
|
|||||||
| height | 表格高度 | `number` | -- | -- |
|
| height | 表格高度 | `number` | -- | -- |
|
||||||
| maxHeight | 表格最大高度 | `number` | -- | -- |
|
| maxHeight | 表格最大高度 | `number` | -- | -- |
|
||||||
| even | 斑马条纹 | `boolean` | `false` | `true` `false` |
|
| even | 斑马条纹 | `boolean` | `false` | `true` `false` |
|
||||||
|
| cellStyle | 列样式 function(row, column, rowIndex, columnIndex) | `string` `function` | -- | -- |
|
||||||
|
| rowStyle | 行样式 function(row, rowIndex) | `string` `function` | -- | -- |
|
||||||
|
| cellClassName | 列类名称 function(row, column, rowIndex, columnIndex) | `string` `function` | -- | -- |
|
||||||
|
| rowClassName | 行类名称 function(row, rowIndex) | `string` `function` | -- | -- |
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
::: title Table 事件
|
::: title Table 事件
|
||||||
|
Loading…
x
Reference in New Issue
Block a user