feat: table add filterMode...
parent
7a1c6b61ba
commit
ee778a2faa
|
@ -158,10 +158,12 @@ export const tableProps = () => {
|
|||
default: undefined,
|
||||
},
|
||||
indentSize: { type: Number as PropType<TableProps['indentSize']>, default: undefined },
|
||||
/** @deprecated Please use `EXPAND_COLUMN` in `columns` directly */
|
||||
expandIconColumnIndex: {
|
||||
type: Number as PropType<TableProps['expandIconColumnIndex']>,
|
||||
default: undefined,
|
||||
},
|
||||
showExpandColumn: { type: Boolean, default: undefined },
|
||||
expandedRowClassName: {
|
||||
type: Function as PropType<TableProps['expandedRowClassName']>,
|
||||
default: undefined,
|
||||
|
@ -494,6 +496,7 @@ const InteralTable = defineComponent<
|
|||
);
|
||||
|
||||
const expandIconColumnIndex = computed(() => {
|
||||
if (props.showExpandColumn === false) return -1;
|
||||
// Adjust expand icon index, no overwrite expandIconColumnIndex if set.
|
||||
if (expandType.value === 'nest' && props.expandIconColumnIndex === undefined) {
|
||||
return props.rowSelection ? 1 : 0;
|
||||
|
|
|
@ -32,14 +32,10 @@ import { defineComponent } from 'vue';
|
|||
import type { TableColumnType } from 'ant-design-vue';
|
||||
// In the fifth row, other columns are merged into first column
|
||||
// by setting it's colSpan to be 0
|
||||
const renderContent = ({ index }: any) => {
|
||||
const obj = {
|
||||
props: {} as any,
|
||||
};
|
||||
const sharedOnCell = (_, index) => {
|
||||
if (index === 4) {
|
||||
obj.props.colSpan = 0;
|
||||
return { colSpan: 0 };
|
||||
}
|
||||
return obj;
|
||||
};
|
||||
|
||||
const data = [
|
||||
|
@ -91,53 +87,42 @@ export default defineComponent({
|
|||
{
|
||||
title: 'Name',
|
||||
dataIndex: 'name',
|
||||
customRender: ({ index }) => {
|
||||
if (index < 4) {
|
||||
return;
|
||||
}
|
||||
return {
|
||||
props: {
|
||||
colSpan: 5,
|
||||
},
|
||||
};
|
||||
},
|
||||
customCell: (_, index) => ({
|
||||
colSpan: index < 4 ? 1 : 5,
|
||||
}),
|
||||
},
|
||||
{
|
||||
title: 'Age',
|
||||
dataIndex: 'age',
|
||||
customRender: renderContent,
|
||||
customCell: sharedOnCell,
|
||||
},
|
||||
{
|
||||
title: 'Home phone',
|
||||
colSpan: 2,
|
||||
dataIndex: 'tel',
|
||||
customRender: ({ index }) => {
|
||||
const obj = {
|
||||
props: {} as any,
|
||||
};
|
||||
customCell: (_, index) => {
|
||||
if (index === 2) {
|
||||
obj.props.rowSpan = 2;
|
||||
return { rowSpan: 2 };
|
||||
}
|
||||
// These two are merged into above cell
|
||||
if (index === 3) {
|
||||
obj.props.rowSpan = 0;
|
||||
return { rowSpan: 0 };
|
||||
}
|
||||
if (index === 4) {
|
||||
obj.props.colSpan = 0;
|
||||
return { colSpan: 0 };
|
||||
}
|
||||
return obj;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: 'Phone',
|
||||
colSpan: 0,
|
||||
dataIndex: 'phone',
|
||||
customRender: renderContent,
|
||||
customCell: sharedOnCell,
|
||||
},
|
||||
{
|
||||
title: 'Address',
|
||||
dataIndex: 'address',
|
||||
customRender: renderContent,
|
||||
customCell: sharedOnCell,
|
||||
},
|
||||
];
|
||||
return {
|
||||
|
|
|
@ -33,7 +33,7 @@ Table with editable rows.
|
|||
<template v-else-if="column.dataIndex === 'operation'">
|
||||
<div class="editable-row-operations">
|
||||
<span v-if="editableData[record.key]">
|
||||
<a @click="save(record.key)">Save</a>
|
||||
<a-typography-link @click="save(record.key)">Save</a-typography-link>
|
||||
<a-popconfirm title="Sure to cancel?" @confirm="cancel(record.key)">
|
||||
<a>Cancel</a>
|
||||
</a-popconfirm>
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
<docs>
|
||||
---
|
||||
order: 6.1
|
||||
version: 3.0
|
||||
title:
|
||||
en-US: Filter in Tree
|
||||
zh-CN: 树型筛选菜单
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
可以使用 `filterMode` 来修改筛选菜单的 UI,可选值有 `menu`(默认)和 `tree`。
|
||||
|
||||
> `filterSearch` 用于开启筛选项的搜索。
|
||||
|
||||
## en-US
|
||||
|
||||
You can use `filterMode` to change default filter interface, options: `menu`(default) and `tree`.
|
||||
|
||||
> `filterSearch` is used for making filter dropdown items searchable.
|
||||
|
||||
</docs>
|
||||
|
||||
<template>
|
||||
<a-table :columns="columns" :data-source="data" @change="onChange"></a-table>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import type { TableProps } from 'ant-design-vue';
|
||||
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const columns: TableProps['columns'] = [
|
||||
{
|
||||
title: 'Name',
|
||||
dataIndex: 'name',
|
||||
filters: [
|
||||
{
|
||||
text: 'Joe',
|
||||
value: 'Joe',
|
||||
},
|
||||
{
|
||||
text: 'Category 1',
|
||||
value: 'Category 1',
|
||||
children: [
|
||||
{
|
||||
text: 'Yellow',
|
||||
value: 'Yellow',
|
||||
},
|
||||
{
|
||||
text: 'Pink',
|
||||
value: 'Pink',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
text: 'Category 2',
|
||||
value: 'Category 2',
|
||||
children: [
|
||||
{
|
||||
text: 'Green',
|
||||
value: 'Green',
|
||||
},
|
||||
{
|
||||
text: 'Black',
|
||||
value: 'Black',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
filterMode: 'tree',
|
||||
filterSearch: true,
|
||||
onFilter: (value, record) => record.name.includes(value),
|
||||
width: '30%',
|
||||
},
|
||||
{
|
||||
title: 'Age',
|
||||
dataIndex: 'age',
|
||||
sorter: (a, b) => a.age - b.age,
|
||||
},
|
||||
{
|
||||
title: 'Address',
|
||||
dataIndex: 'address',
|
||||
filters: [
|
||||
{
|
||||
text: 'London',
|
||||
value: 'London',
|
||||
},
|
||||
{
|
||||
text: 'New York',
|
||||
value: 'New York',
|
||||
},
|
||||
],
|
||||
onFilter: (value, record) => record.address.startsWith(value),
|
||||
filterSearch: true,
|
||||
width: '40%',
|
||||
},
|
||||
];
|
||||
|
||||
const data = [
|
||||
{
|
||||
key: '1',
|
||||
name: 'John Brown',
|
||||
age: 32,
|
||||
address: 'New York No. 1 Lake Park',
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
name: 'Jim Green',
|
||||
age: 42,
|
||||
address: 'London No. 1 Lake Park',
|
||||
},
|
||||
{
|
||||
key: '3',
|
||||
name: 'Joe Black',
|
||||
age: 32,
|
||||
address: 'Sidney No. 1 Lake Park',
|
||||
},
|
||||
{
|
||||
key: '4',
|
||||
name: 'Jim Red',
|
||||
age: 32,
|
||||
address: 'London No. 2 Lake Park',
|
||||
},
|
||||
];
|
||||
|
||||
function onChange(pagination, filters, sorter, extra) {
|
||||
console.log('params', pagination, filters, sorter, extra);
|
||||
}
|
||||
|
||||
return {
|
||||
data,
|
||||
columns,
|
||||
onChange,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
|
@ -5,7 +5,6 @@
|
|||
<Bordered />
|
||||
<Ellipsis />
|
||||
<ColspanRowspan />
|
||||
<CustomFilterPanel />
|
||||
<EditCell />
|
||||
<EditRow />
|
||||
<ExpandChildren />
|
||||
|
@ -14,9 +13,10 @@
|
|||
<FixedColumns />
|
||||
<FixedHeader />
|
||||
<GroupingColumns />
|
||||
<Head />
|
||||
<MultipleSorter />
|
||||
<NestedTable />
|
||||
<Head />
|
||||
<CustomFilterPanel />
|
||||
<ResetFilter />
|
||||
<RowSelectionAndOperation />
|
||||
<RowSelectionCustom />
|
||||
|
|
|
@ -0,0 +1,80 @@
|
|||
<docs>
|
||||
---
|
||||
order: 14.1
|
||||
version: 3.0
|
||||
title:
|
||||
en-US: Order Specific Column
|
||||
zh-CN: 特殊列排序
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
你可以通过 `Table.EXPAND_COLUMN` 和 `Table.SELECT_COLUMN` 来控制选择和展开列的顺序。
|
||||
|
||||
## en-US
|
||||
|
||||
You can control the order of the expand and select columns by using `Table.EXPAND_COLUMN` and `Table.SELECT_COLUMN`.
|
||||
|
||||
</docs>
|
||||
|
||||
<template>
|
||||
<a-table :columns="columns" :data-source="data" :row-selection="{}">
|
||||
<template #expandedRowRender="{ record }">
|
||||
<p style="margin: 0">
|
||||
{{ record.description }}
|
||||
</p>
|
||||
</template>
|
||||
</a-table>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import { Table } from 'ant-design-vue';
|
||||
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const columns = [
|
||||
{ title: 'Name', dataIndex: 'name', key: 'name' },
|
||||
Table.EXPAND_COLUMN,
|
||||
{ title: 'Age', dataIndex: 'age', key: 'age' },
|
||||
Table.SELECTION_COLUMN,
|
||||
{ title: 'Address', dataIndex: 'address', key: 'address' },
|
||||
];
|
||||
|
||||
const data = [
|
||||
{
|
||||
key: 1,
|
||||
name: 'John Brown',
|
||||
age: 32,
|
||||
address: 'New York No. 1 Lake Park',
|
||||
description:
|
||||
'My name is John Brown, I am 32 years old, living in New York No. 1 Lake Park.',
|
||||
},
|
||||
{
|
||||
key: 2,
|
||||
name: 'Jim Green',
|
||||
age: 42,
|
||||
address: 'London No. 1 Lake Park',
|
||||
description: 'My name is Jim Green, I am 42 years old, living in London No. 1 Lake Park.',
|
||||
},
|
||||
{
|
||||
key: 3,
|
||||
name: 'Not Expandable',
|
||||
age: 29,
|
||||
address: 'Jiangsu No. 1 Lake Park',
|
||||
description: 'This not expandable',
|
||||
},
|
||||
{
|
||||
key: 4,
|
||||
name: 'Joe Black',
|
||||
age: 32,
|
||||
address: 'Sidney No. 1 Lake Park',
|
||||
description: 'My name is Joe Black, I am 32 years old, living in Sidney No. 1 Lake Park.',
|
||||
},
|
||||
];
|
||||
return {
|
||||
data,
|
||||
columns,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
|
@ -22,9 +22,15 @@ For long table,need to scroll to view the header and scroll bar,then you can
|
|||
<template v-if="column.key === 'operation'"><a>action</a></template>
|
||||
</template>
|
||||
<template #summary>
|
||||
<a-table-summary>
|
||||
<a-table-summary :fixed="fixedTop ? 'top' : 'bottom'">
|
||||
<a-table-summary-row>
|
||||
<a-table-summary-cell :index="0" :col-span="2">Fix Left</a-table-summary-cell>
|
||||
<a-table-summary-cell :index="0" :col-span="2">
|
||||
<a-switch
|
||||
v-model:checked="fixedTop"
|
||||
checked-children="Fixed Top"
|
||||
un-checked-children="Fixed Top"
|
||||
></a-switch>
|
||||
</a-table-summary-cell>
|
||||
<a-table-summary-cell :index="2" :col-span="8">Scroll Context</a-table-summary-cell>
|
||||
<a-table-summary-cell :index="10">Fix Right</a-table-summary-cell>
|
||||
</a-table-summary-row>
|
||||
|
@ -117,6 +123,7 @@ export default defineComponent({
|
|||
return {
|
||||
data,
|
||||
columns,
|
||||
fixedTop: ref(false),
|
||||
};
|
||||
},
|
||||
});
|
||||
|
|
|
@ -3,10 +3,13 @@ import { renderSlot } from 'vue';
|
|||
import type { Ref } from 'vue';
|
||||
import type { ContextSlots } from '../context';
|
||||
import type { TransformColumns, ColumnsType } from '../interface';
|
||||
import { SELECTION_COLUMN } from './useSelection';
|
||||
import { EXPAND_COLUMN } from '../../vc-table';
|
||||
|
||||
function fillSlots<RecordType>(columns: ColumnsType<RecordType>, contextSlots: Ref<ContextSlots>) {
|
||||
const $slots = contextSlots.value;
|
||||
return columns.map(column => {
|
||||
if (column === SELECTION_COLUMN || column === EXPAND_COLUMN) return column;
|
||||
const cloneColumn = { ...column };
|
||||
const { slots = {} } = cloneColumn;
|
||||
cloneColumn.__originColumn__ = column;
|
||||
|
|
|
@ -12,6 +12,7 @@ import type {
|
|||
Key,
|
||||
TableLocale,
|
||||
GetPopupContainer,
|
||||
FilterSearchType,
|
||||
} from '../../interface';
|
||||
import FilterDropdownMenuWrapper from './FilterWrapper';
|
||||
import type { FilterState } from '.';
|
||||
|
@ -25,6 +26,11 @@ import type { CheckboxChangeEvent, EventHandler } from '../../../_util/EventInte
|
|||
import FilterSearch from './FilterSearch';
|
||||
import Tree from '../../../tree';
|
||||
|
||||
interface FilterRestProps {
|
||||
confirm?: Boolean;
|
||||
closeDropdown?: Boolean;
|
||||
}
|
||||
|
||||
const { SubMenu, Item: MenuItem } = Menu;
|
||||
|
||||
function hasSubMenu(filters: ColumnFilterItem[]) {
|
||||
|
@ -44,12 +50,14 @@ function renderFilterItems({
|
|||
filteredKeys,
|
||||
filterMultiple,
|
||||
searchValue,
|
||||
filterSearch,
|
||||
}: {
|
||||
filters: ColumnFilterItem[];
|
||||
prefixCls: string;
|
||||
filteredKeys: Key[];
|
||||
filterMultiple: boolean;
|
||||
searchValue: string;
|
||||
filterSearch: FilterSearchType;
|
||||
}) {
|
||||
return filters.map((filter, index) => {
|
||||
const key = String(filter.value);
|
||||
|
@ -67,6 +75,7 @@ function renderFilterItems({
|
|||
filteredKeys,
|
||||
filterMultiple,
|
||||
searchValue,
|
||||
filterSearch,
|
||||
})}
|
||||
</SubMenu>
|
||||
);
|
||||
|
@ -81,6 +90,9 @@ function renderFilterItems({
|
|||
</MenuItem>
|
||||
);
|
||||
if (searchValue.trim()) {
|
||||
if (typeof filterSearch === 'function') {
|
||||
return filterSearch(searchValue, filter) ? item : undefined;
|
||||
}
|
||||
return searchValueMatched(searchValue, filter.text) ? item : undefined;
|
||||
}
|
||||
return item;
|
||||
|
@ -131,7 +143,7 @@ export default defineComponent<FilterDropdownProps<any>>({
|
|||
(props.filterState.filteredKeys?.length || props.filterState.forceFiltered)
|
||||
),
|
||||
);
|
||||
|
||||
const filterFlattenKeys = computed(() => flattenKeys(props.column?.filters));
|
||||
const filterDropdownRef = computed(() => {
|
||||
const { filterDropdown, slots = {}, customFilterDropdown } = props.column;
|
||||
return (
|
||||
|
@ -188,6 +200,8 @@ export default defineComponent<FilterDropdownProps<any>>({
|
|||
{ immediate: true },
|
||||
);
|
||||
|
||||
// const expandKeys = shallowRef(filterFlattenKeys.value.slice());
|
||||
// const onExpandChange = keys => (expandKeys.value = keys);
|
||||
const openKeys = shallowRef([]);
|
||||
|
||||
const openRef = ref();
|
||||
|
@ -241,7 +255,15 @@ export default defineComponent<FilterDropdownProps<any>>({
|
|||
internalTriggerFilter(filteredKeys.value);
|
||||
};
|
||||
|
||||
const onReset = () => {
|
||||
const onReset = (
|
||||
{ confirm, closeDropdown }: FilterRestProps = { confirm: false, closeDropdown: false },
|
||||
) => {
|
||||
if (confirm) {
|
||||
internalTriggerFilter([]);
|
||||
}
|
||||
if (closeDropdown) {
|
||||
triggerVisible(false);
|
||||
}
|
||||
searchValue.value = '';
|
||||
filteredKeys.value = [];
|
||||
};
|
||||
|
@ -270,7 +292,7 @@ export default defineComponent<FilterDropdownProps<any>>({
|
|||
|
||||
const onCheckAll = (e: CheckboxChangeEvent) => {
|
||||
if (e.target.checked) {
|
||||
const allFilterKeys = flattenKeys(props.column?.filters).map(key => String(key));
|
||||
const allFilterKeys = filterFlattenKeys.value;
|
||||
filteredKeys.value = allFilterKeys;
|
||||
} else {
|
||||
filteredKeys.value = [];
|
||||
|
@ -289,6 +311,8 @@ export default defineComponent<FilterDropdownProps<any>>({
|
|||
}
|
||||
return item;
|
||||
});
|
||||
|
||||
const treeData = computed(() => getTreeData({ filters: props.column.filters }));
|
||||
// ======================== Style ========================
|
||||
const dropdownMenuClass = computed(() =>
|
||||
classNames({
|
||||
|
@ -338,6 +362,10 @@ export default defineComponent<FilterDropdownProps<any>>({
|
|||
<Checkbox
|
||||
class={`${tablePrefixCls}-filter-dropdown-checkall`}
|
||||
onChange={onCheckAll}
|
||||
checked={selectedKeys.length === filterFlattenKeys.value.length}
|
||||
indeterminate={
|
||||
selectedKeys.length > 0 && selectedKeys.length < filterFlattenKeys.value.length
|
||||
}
|
||||
>
|
||||
{locale.filterCheckall}
|
||||
</Checkbox>
|
||||
|
@ -353,9 +381,11 @@ export default defineComponent<FilterDropdownProps<any>>({
|
|||
checkedKeys={selectedKeys}
|
||||
selectedKeys={selectedKeys}
|
||||
showIcon={false}
|
||||
treeData={getTreeData({ filters: column.filters })}
|
||||
treeData={treeData.value}
|
||||
autoExpandParent
|
||||
defaultExpandAll
|
||||
// expandedKeys={expandKeys.value as Key[]}
|
||||
// onExpand={onExpandChange}
|
||||
filterTreeNode={
|
||||
searchValue.value.trim()
|
||||
? node => searchValueMatched(searchValue.value, node.title)
|
||||
|
@ -390,6 +420,7 @@ export default defineComponent<FilterDropdownProps<any>>({
|
|||
default: () =>
|
||||
renderFilterItems({
|
||||
filters: column.filters || [],
|
||||
filterSearch: filterSearch.value,
|
||||
prefixCls,
|
||||
filteredKeys: filteredKeys.value,
|
||||
filterMultiple,
|
||||
|
@ -430,7 +461,7 @@ export default defineComponent<FilterDropdownProps<any>>({
|
|||
type="link"
|
||||
size="small"
|
||||
disabled={selectedKeys.length === 0}
|
||||
onClick={onReset}
|
||||
onClick={() => onReset()}
|
||||
>
|
||||
{locale.filterReset}
|
||||
</Button>
|
||||
|
|
|
@ -35,7 +35,7 @@ export const SELECTION_COLUMN = {} as const;
|
|||
export const SELECTION_ALL = 'SELECT_ALL' as const;
|
||||
export const SELECTION_INVERT = 'SELECT_INVERT' as const;
|
||||
export const SELECTION_NONE = 'SELECT_NONE' as const;
|
||||
|
||||
const EMPTY_LIST: Key[] = [];
|
||||
interface UseSelectionConfig<RecordType> {
|
||||
prefixCls: Ref<string>;
|
||||
pageData: Ref<RecordType[]>;
|
||||
|
@ -87,7 +87,7 @@ export default function useSelection<RecordType>(
|
|||
const [mergedSelectedKeys, setMergedSelectedKeys] = useMergedState(
|
||||
mergedRowSelection.value.selectedRowKeys ||
|
||||
mergedRowSelection.value.defaultSelectedRowKeys ||
|
||||
[],
|
||||
EMPTY_LIST,
|
||||
{
|
||||
value: computed(() => mergedRowSelection.value.selectedRowKeys),
|
||||
},
|
||||
|
|
|
@ -82,9 +82,10 @@ Specify `dataSource` of Table as an array of data.
|
|||
| expandFixed | Set column to be fixed: `true`(same as left) `'left'` `'right'` | boolean \| string | false | 3.0 |
|
||||
| expandIcon | Customize row expand Icon. | Function(props):VNode \| v-slot:expandIcon="props" | - | |
|
||||
| expandRowByClick | Whether to expand row by clicking anywhere in the whole row | boolean | `false` | |
|
||||
| expandIconColumnIndex | Customize expand icon column index. Not render when `-1` | 0 | |
|
||||
| footer | Table footer renderer | Function(currentPageData)\| v-slot:footer="currentPageData" | |
|
||||
| indentSize | Indent size in pixels of tree data | number | 15 | |
|
||||
| rowExpandable | Enable row can be expandable | (record) => boolean | - | |
|
||||
| showExpandColumn | Show expand column | boolean | true | 3.0 |
|
||||
| loading | Loading status of table | boolean\|[object](/components/spin) | `false` |
|
||||
| locale | i18n text including filter, sort, empty text, etc | object | filterConfirm: 'Ok' <br /> filterReset: 'Reset' <br /> emptyText: 'No Data' | |
|
||||
| pagination | Config of pagination. You can ref table pagination [config](#pagination) or full [`pagination`](/components/pagination/) document, hide it by setting it to `false` | object | | |
|
||||
|
@ -109,10 +110,6 @@ Specify `dataSource` of Table as an array of data.
|
|||
| summary | Summary content | v-slot:summary | - | 3.0 |
|
||||
| transformCellText | The data can be changed again before rendering, generally used for the default configuration of empty data. You can configured globally through [ConfigProvider](/components/config-provider-cn/) | Function({ text, column, record, index }) => any, The `text` here is the data processed by other defined cell api, and it may be of type VNode \| string \| number | - | 1.5.4 | |
|
||||
|
||||
- `expandFixed`
|
||||
- When set to true or `left` and `expandIconColumnIndex` is not set or is 0, enable fixed
|
||||
- When set to true or `right` and `expandIconColumnIndex` is set to the number of table columns, enable fixed
|
||||
|
||||
### Events
|
||||
|
||||
| Events Name | Description | Arguments |
|
||||
|
@ -166,10 +163,12 @@ One of the Table `columns` prop for describing the table's columns, Column has t
|
|||
| filteredValue | Controlled filtered value, filter icon will highlight | string\[] | - | |
|
||||
| filterIcon | Customized filter icon | ({filtered: boolean, column: Column}) | `false` | |
|
||||
| filterMultiple | Whether multiple filters can be selected | boolean | `true` | |
|
||||
| filterMode | To specify the filter interface | 'menu' \| 'tree' | 'menu' | 3.0 |
|
||||
| filterSearch | Whether to be searchable for filter menu | Boolean | false | 3.0 |
|
||||
| filters | Filter menu config | object\[] | - | |
|
||||
| fixed | Set column to be fixed: `true`(same as left) `'left'` `'right'` | boolean\|string | `false` | |
|
||||
| key | Unique key of this column, you can ignore this prop if you've set a unique `dataIndex` | string | - | |
|
||||
| customRender | Renderer of the table cell. The return value should be a VNode, or an object for colSpan/rowSpan config | Function({text, record, index}) {} | - | |
|
||||
| customRender | Renderer of the table cell. The return value should be a VNode | Function({text, record, index}) {} | - | |
|
||||
| responsive | The list of breakpoints at which to display this column. Always visible if not set. | [Breakpoint](#Breakpoint)\[] | - | 3.0 |
|
||||
| sorter | Sort function for local sort, see [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)'s compareFunction. If you need sort buttons only, set to `true` | Function\|boolean | - | |
|
||||
| sortOrder | Order of sorted values: `'ascend'` `'descend'` `false` | boolean\|string | - | |
|
||||
|
|
|
@ -86,7 +86,6 @@ cover: https://gw.alipayobjects.com/zos/alicdn/f-SbcX2Lx/Table.svg
|
|||
| expandFixed | 控制展开图标是否固定,可选 true `left` `right` | boolean \| string | false | 3.0 |
|
||||
| expandIcon | 自定义展开图标 | Function(props):VNode \| v-slot:expandIcon="props" | - | |
|
||||
| expandRowByClick | 通过点击行来展开子行 | boolean | `false` | |
|
||||
| expandIconColumnIndex | 自定义展开按钮的列顺序,`-1` 时不展示 | number | - | |
|
||||
| footer | 表格尾部 | Function(currentPageData)\|v-slot:footer="currentPageData" | | |
|
||||
| getPopupContainer | 设置表格内各类浮层的渲染节点,如筛选菜单 | (triggerNode) => HTMLElement | `() => TableHtmlElement` | 1.5.0 |
|
||||
| loading | 页面是否加载中 | boolean\|[object](/components/spin-cn) | false | |
|
||||
|
@ -105,6 +104,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/f-SbcX2Lx/Table.svg
|
|||
| title | 表格标题 | Function(currentPageData)\|v-slot:title="currentPageData" | | |
|
||||
| indentSize | 展示树形数据时,每层缩进的宽度,以 px 为单位 | number | 15 | |
|
||||
| rowExpandable | 设置是否允许行展开 | (record) => boolean | - | 3.0 |
|
||||
| showExpandColumn | 设置是否展示行展开列 | boolean | true | 3.0 |
|
||||
| customHeaderRow | 设置头部行属性 | Function(columns, index) | - | |
|
||||
| customRow | 设置行属性 | Function(record, index) | - | |
|
||||
| headerCell | 个性化头部单元格 | v-slot:headerCell="{title, column}" | - | 3.0 |
|
||||
|
@ -115,10 +115,6 @@ cover: https://gw.alipayobjects.com/zos/alicdn/f-SbcX2Lx/Table.svg
|
|||
| summary | 总结栏 | v-slot:summary | - | 3.0 |
|
||||
| transformCellText | 数据渲染前可以再次改变,一般用于空数据的默认配置,可以通过 [ConfigProvider](/components/config-provider-cn/) 全局统一配置 | Function({ text, column, record, index }) => any,此处的 text 是经过其它定义单元格 api 处理后的数据,有可能是 VNode \| string \| number 类型 | - | 1.5.4 |
|
||||
|
||||
- `expandFixed`
|
||||
- 当设置为 true 或 `left` 且 `expandIconColumnIndex` 未设置或为 0 时,开启固定
|
||||
- 当设置为 true 或 `right` 且 `expandIconColumnIndex` 设置为表格列数时,开启固定
|
||||
|
||||
### 事件
|
||||
|
||||
| 事件名称 | 说明 | 回调参数 |
|
||||
|
@ -171,10 +167,12 @@ cover: https://gw.alipayobjects.com/zos/alicdn/f-SbcX2Lx/Table.svg
|
|||
| filteredValue | 筛选的受控属性,外界可用此控制列的筛选状态,值为已筛选的 value 数组 | string\[] | - | |
|
||||
| filterIcon | 自定义 filter 图标。 | VNode \| ({filtered: boolean, column: Column}) => vNode | false | |
|
||||
| filterMultiple | 是否多选 | boolean | true | |
|
||||
| filterMode | 指定筛选菜单的用户界面 | 'menu' \| 'tree' | 'menu' | 3.0 |
|
||||
| filterSearch | 筛选菜单项是否可搜索 | Boolean | false | 3.0 |
|
||||
| filters | 表头的筛选菜单项 | object\[] | - | |
|
||||
| fixed | 列是否固定,可选 `true`(等效于 left) `'left'` `'right'` | boolean\|string | false | |
|
||||
| key | Vue 需要的 key,如果已经设置了唯一的 `dataIndex`,可以忽略这个属性 | string | - | |
|
||||
| customRender | 生成复杂数据的渲染函数,参数分别为当前行的值,当前行数据,行索引,@return 里面可以设置表格行/列合并,可参考 demo 表格行/列合并 | Function({text, record, index, column}) {} | - | |
|
||||
| customRender | 生成复杂数据的渲染函数,参数分别为当前行的值,当前行数据,行索引 | Function({text, record, index, column}) {} | - | |
|
||||
| responsive | 响应式 breakpoint 配置列表。未设置则始终可见。 | [Breakpoint](#Breakpoint)\[] | - | 3.0 |
|
||||
| showSorterTooltip | 表头显示下一次排序的 tooltip 提示, 覆盖 table 中 `showSorterTooltip` | boolean \| [Tooltip props](/components/tooltip/#API) | true | |
|
||||
| sorter | 排序函数,本地排序使用一个函数(参考 [Array.sort](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) 的 compareFunction),需要服务端排序可设为 true | Function\|boolean | - | |
|
||||
|
|
|
@ -73,6 +73,7 @@ export type ColumnTitle<RecordType> = VueNode | ((props: ColumnTitleProps<Record
|
|||
|
||||
export type FilterValue = (Key | boolean)[];
|
||||
export type FilterKey = Key[] | null;
|
||||
export type FilterSearchType = boolean | ((input: string, record: {}) => boolean);
|
||||
export interface FilterConfirmProps {
|
||||
closeDropdown: boolean;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import classNames from '../../_util/classNames';
|
||||
import { flattenChildren, isValidElement, parseStyleText } from '../../_util/props-util';
|
||||
import type { CSSProperties, TdHTMLAttributes } from 'vue';
|
||||
import type { CSSProperties } from 'vue';
|
||||
import { computed, defineComponent, isVNode, renderSlot } from 'vue';
|
||||
|
||||
import type {
|
||||
|
@ -13,6 +13,7 @@ import type {
|
|||
AlignType,
|
||||
CellEllipsisType,
|
||||
TransformCellText,
|
||||
AdditionalProps,
|
||||
} from '../interface';
|
||||
import { getPathValue, validateValue } from '../utils/valueUtil';
|
||||
import { useInjectSlots } from '../../table/context';
|
||||
|
@ -61,7 +62,7 @@ export interface CellProps<RecordType = DefaultRecordType> {
|
|||
/** @private Used for `expandable` with nest tree */
|
||||
appendNode?: any;
|
||||
|
||||
additionalProps?: TdHTMLAttributes;
|
||||
additionalProps?: AdditionalProps;
|
||||
|
||||
rowType?: 'header' | 'body' | 'footer';
|
||||
|
||||
|
@ -106,10 +107,18 @@ export default defineComponent<CellProps>({
|
|||
const contextSlots = useInjectSlots();
|
||||
const { onHover, startRow, endRow } = useInjectHover();
|
||||
const colSpan = computed(() => {
|
||||
return props.colSpan ?? (props.additionalProps?.colspan as number);
|
||||
return (
|
||||
props.colSpan ??
|
||||
props.additionalProps?.colSpan ??
|
||||
(props.additionalProps?.colspan as number)
|
||||
);
|
||||
});
|
||||
const rowSpan = computed(() => {
|
||||
return props.rowSpan ?? (props.additionalProps?.rowspan as number);
|
||||
return (
|
||||
props.rowSpan ??
|
||||
props.additionalProps?.rowSpan ??
|
||||
(props.additionalProps?.rowspan as number)
|
||||
);
|
||||
});
|
||||
const hovering = computed(() => {
|
||||
const { index } = props;
|
||||
|
|
|
@ -43,9 +43,7 @@ export default defineComponent<SummaryCellProps>({
|
|||
align={align}
|
||||
colSpan={mergedColSpan}
|
||||
rowSpan={rowSpan}
|
||||
customRender={() => ({
|
||||
children: slots.default?.(),
|
||||
})}
|
||||
customRender={() => slots.default?.()}
|
||||
{...fixedInfo}
|
||||
/>
|
||||
);
|
||||
|
|
|
@ -109,6 +109,7 @@ export interface TableProps<RecordType = DefaultRecordType> {
|
|||
defaultExpandAllRows?: boolean;
|
||||
indentSize?: number;
|
||||
expandIconColumnIndex?: number;
|
||||
showExpandColumn?: boolean;
|
||||
expandedRowClassName?: RowClassName<RecordType>;
|
||||
childrenColumnName?: string;
|
||||
rowExpandable?: (record: RecordType) => boolean;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* - onFilterDropdownVisibleChange
|
||||
*/
|
||||
|
||||
import type { CSSProperties, HTMLAttributes, Ref, TdHTMLAttributes } from 'vue';
|
||||
import type { CSSProperties, Ref, TdHTMLAttributes } from 'vue';
|
||||
|
||||
export type Key = number | string;
|
||||
|
||||
|
@ -132,13 +132,16 @@ export interface StickyOffsets {
|
|||
right: readonly number[];
|
||||
isSticky?: boolean;
|
||||
}
|
||||
|
||||
export type AdditionalProps = TdHTMLAttributes & {
|
||||
colSpan?: number;
|
||||
rowSpan?: number;
|
||||
};
|
||||
// ================= Customized =================
|
||||
export type GetComponentProps<DataType> = (
|
||||
data: DataType,
|
||||
index?: number,
|
||||
column?: ColumnType<any>,
|
||||
) => Omit<HTMLAttributes | TdHTMLAttributes, 'style'> & { style?: CSSProperties };
|
||||
) => AdditionalProps;
|
||||
|
||||
// type Component<P> = DefineComponent<P> | FunctionalComponent<P> | string;
|
||||
|
||||
|
@ -195,9 +198,11 @@ export interface LegacyExpandableProps<RecordType> {
|
|||
defaultExpandAllRows?: boolean;
|
||||
|
||||
indentSize?: number;
|
||||
|
||||
/** @deprecated Please use `EXPAND_COLUMN` in `columns` directly */
|
||||
expandIconColumnIndex?: number;
|
||||
|
||||
showExpandColumn?: boolean;
|
||||
|
||||
expandedRowClassName?: RowClassName<RecordType>;
|
||||
|
||||
childrenColumnName?: string;
|
||||
|
|
Loading…
Reference in New Issue