Skip to content

Commit

Permalink
20220925 feature table (#1740)
Browse files Browse the repository at this point in the history
* fix(table): selected change value is not right

* feat(table): some features and bugs

* test(unit): update snapshots

* docs(table): demos

* fix(table): sort highlight

* fix(table): remove duplicate resizable

* feat(table): support dynamic treeNodeColumnIndex
  • Loading branch information
chaishi authored Sep 27, 2022
1 parent 75944c6 commit 466033b
Show file tree
Hide file tree
Showing 28 changed files with 999 additions and 751 deletions.
30 changes: 18 additions & 12 deletions src/table/_example/base.vue
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
<template>
<div class="tdesign-demo-block-column-large">
<t-space direction="vertical">
<!-- 按钮操作区域 -->
<div>
<t-radio-group v-model="size" variant="default-filled">
<t-radio-button value="small">小尺寸</t-radio-button>
<t-radio-button value="medium">中尺寸</t-radio-button>
<t-radio-button value="large">大尺寸</t-radio-button>
</t-radio-group>
<br /><br />
<t-radio-group v-model="size" variant="default-filled">
<t-radio-button value="small">小尺寸</t-radio-button>
<t-radio-button value="medium">中尺寸</t-radio-button>
<t-radio-button value="large">大尺寸</t-radio-button>
</t-radio-group>

<t-space>
<t-checkbox v-model="stripe"> 显示斑马纹 </t-checkbox>
<t-checkbox v-model="bordered"> 显示表格边框 </t-checkbox>
<t-checkbox v-model="hover"> 显示悬浮效果 </t-checkbox>
<t-checkbox v-model="tableLayout"> 宽度自适应 </t-checkbox>
</div>
<t-checkbox v-model="showHeader"> 显示表头 </t-checkbox>
</t-space>

<!-- 当数据为空需要占位时,会显示 cellEmptyContent -->
<t-table
Expand All @@ -25,10 +26,11 @@
:table-layout="tableLayout ? 'auto' : 'fixed'"
:size="size"
:pagination="pagination"
:show-header="showHeader"
cell-empty-content="-"
@row-click="handleRowClick"
/>
</div>
</t-space>
</template>

<script setup lang="jsx">
Expand All @@ -52,16 +54,18 @@ for (let i = 0; i < total; i++) {
const columns = [
{
width: '100',
colKey: 'index',
// 序号列,设置 colKey = serial-number 即可
colKey: 'serial-number',
title: '序号',
width: '100',
// 对齐方式
align: 'center',
// 设置列类名
className: 'custom-column-class-name',
// 设置列属性
attrs: {
'data-id': 'first-column',
style: {},
},
},
{
Expand Down Expand Up @@ -89,6 +93,7 @@ const columns = [
* 3.值类型为 Object,则自动透传属性到 Tooltip 组件。
*/
ellipsis: true,
ellipsisTitle: false,
// 透传省略内容浮层 Tooltip 组件全部特性,示例代码有效,勿删!!!
// ellipsis: { placement: 'bottom', destroyOnClose: false },
Expand Down Expand Up @@ -116,6 +121,7 @@ const bordered = ref(true);
const hover = ref(false);
const tableLayout = ref(false);
const size = ref('medium');
const showHeader = ref(true);
const handleRowClick = (e) => {
console.log(e);
Expand Down
10 changes: 7 additions & 3 deletions src/table/_example/filter-controlled.vue
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ const columns = computed(() => [
},
]);
const filterValue = ref({});
const filterValue = ref({ lastName: [], createTime: [] });
const data = ref([...initData]);
const bordered = ref(true);
Expand All @@ -147,7 +147,7 @@ const request = (filters) => {
if (result && filters.email) {
result = item.email.indexOf(filters.email) !== -1;
}
if (result && filters.createTime) {
if (result && filters.createTime && filters.createTime.length) {
result = item.createTime === filters.createTime;
}
return result;
Expand All @@ -157,7 +157,11 @@ const request = (filters) => {
};
const onFilterChange = (filters) => {
filterValue.value = filters;
filterValue.value = {
...filters,
createTime: filters.createTime || [],
lastName: filters.lastName || [],
};
console.log(filters);
request(filters);
};
Expand Down
3 changes: 0 additions & 3 deletions src/table/_example/merge-cells.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
:data="data"
:columns="columns"
row-key="i"
:size="size"
:rowspan-and-colspan="rowspanAndColspan"
resizable
table-layout="fixed"
Expand Down Expand Up @@ -84,6 +83,4 @@ const rowspanAndColspan = ({ col, rowIndex, colIndex }) => {
};
}
};
const size = 'small';
</script>
4 changes: 2 additions & 2 deletions src/table/_example/multi-header.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
<!-- 注意控制父元素宽度 -->
<div style="width: 100%" class="tdesign-demo-block-column-large tdesign-demo-table-multi-header">
<!-- 按钮操作区域 -->
<div>
<t-space>
<t-checkbox v-model="bordered">显示表格边框</t-checkbox>
<t-checkbox v-model="fixedHeader">显示固定表头</t-checkbox>
<!-- 为保证组件收益最大化,当数据量小于 `100` 时,无论虚拟滚动的配置是否存在,组件内部都不会开启虚拟滚动 -->
<!-- <t-checkbox v-model="virtualScroll">虚拟滚动</t-checkbox> -->
<t-checkbox v-model="fixedLeftCol">固定左侧列</t-checkbox>
<t-checkbox v-model="fixedRightCol">固定右侧列</t-checkbox>
<t-checkbox v-model="headerAffixedTop">表头吸顶</t-checkbox>
</div>
</t-space>

<!-- tableContentWidth 必须大于表格的外层宽度,否则请设置 width: 100% -->
<!-- 多级表头中,如果要使用固定列功能,则必须设置 colKey 和 fixed -->
Expand Down
2 changes: 2 additions & 0 deletions src/table/_example/select-single.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import { ref } from 'vue';
const columns = [
{
// title: '单选',
// align: 'center',
colKey: 'row-select',
type: 'single',
// 允许单选(Radio)取消行选中
Expand Down
6 changes: 6 additions & 0 deletions src/table/_example/single-sort.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
:data="data"
:sort="sort"
:hide-sort-tips="hideSortTips"
:show-sort-column-bg-color="true"
bordered
@sort-change="sortChange"
@change="onChange"
Expand All @@ -46,6 +47,11 @@ const columns = [
width: 100,
sortType: 'all',
sorter: true,
// 自定义列,或单元格类名
// className: (params) => {
// console.log(params);
// return 'status-class-bg';
// },
},
{
colKey: 'survivalTime',
Expand Down
4 changes: 3 additions & 1 deletion src/table/_example/tree.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
drag-sort="row-handler"
:data="data"
:columns="columns"
:tree="{ childrenKey: 'list', treeNodeColumnIndex: 2, indent: 25 }"
:tree="treeConfig"
:tree-expand-and-fold-icon="treeExpandIcon"
:pagination="pagination"
:before-drag-sort="beforeDragSort"
Expand Down Expand Up @@ -128,6 +128,8 @@ const table = ref(null);
const data = ref(getData());
const lazyLoadingData = ref(null);
const treeConfig = reactive({ childrenKey: 'list', treeNodeColumnIndex: 2, indent: 25 });
const resetData = () => {
// 需要更新数据地址空间
const newData = getData();
Expand Down
5 changes: 5 additions & 0 deletions src/table/base-table-props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@ export default {
scroll: {
type: Object as PropType<TdBaseTableProps['scroll']>,
},
/** 是否显示表头 */
showHeader: {
type: Boolean,
default: true,
},
/** 表格尺寸 */
size: {
type: String as PropType<TdBaseTableProps['size']>,
Expand Down
139 changes: 67 additions & 72 deletions src/table/base-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,54 @@ export default defineComponent({
}
const defaultColWidth = this.tableLayout === 'fixed' && this.isWidthOverflow ? '100px' : undefined;

const renderColGroup = () => (
<colgroup>
{columns.map((col) => {
const style: Styles = {
width: formatCSSUnit(this.thWidthList[col.colKey] || col.width) || defaultColWidth,
};
if (col.minWidth) {
style.minWidth = formatCSSUnit(col.minWidth);
}
return <col key={col.colKey} style={style}></col>;
})}
</colgroup>
);

const renderAffixedHeader = () => {
if (this.showHeader === false) return null;
return (
!!(this.isVirtual || this.headerAffixedTop) &&
(this.headerAffixedTop ? (
<Affix offsetTop={0} {...getAffixProps(this.headerAffixedTop)} onFixedChange={this.onFixedChange}>
{affixHeaderWithWrap}
</Affix>
) : (
this.isFixedHeader && affixHeaderWithWrap
))
);
};

const renderAffixedHorizontalScrollbar = () => (
<Affix
offsetBottom={0}
{...getAffixProps(this.horizontalScrollAffixedBottom)}
style={{ marginTop: `-${this.scrollbarWidth * 2}px` }}
>
<div
ref="horizontalScrollbarRef"
class={['scrollbar', this.tableBaseClass.obviousScrollbar]}
style={{
width: `${this.tableWidth}px`,
overflow: 'auto',
opacity: Number(this.showAffixFooter),
}}
>
<div style={{ width: `${this.tableElmWidth}px`, height: '5px' }}></div>
</div>
</Affix>
);

/**
* Affixed Header
*/
Expand Down Expand Up @@ -332,17 +380,7 @@ export default defineComponent({
>
<table class={this.tableElmClasses} style={{ ...this.tableElementStyles, width: `${this.tableElmWidth}px` }}>
{/* 此处和 Vue2 不同,Vue3 里面必须每一处单独写 <colgroup> */}
<colgroup>
{columns.map((col) => {
const style: Styles = {
width: formatCSSUnit(this.thWidthList[col.colKey] || col.width) || defaultColWidth,
};
if (col.minWidth) {
style.minWidth = formatCSSUnit(col.minWidth);
}
return <col key={col.colKey} style={style}></col>;
})}
</colgroup>
{renderColGroup()}
<THead
v-slots={this.$slots}
isFixedHeader={this.isFixedHeader}
Expand Down Expand Up @@ -390,17 +428,7 @@ export default defineComponent({
>
<table class={this.tableElmClasses} style={{ ...this.tableElementStyles, width: `${this.tableElmWidth}px` }}>
{/* 此处和 Vue2 不同,Vue3 里面必须每一处单独写 <colgroup> */}
<colgroup>
{columns.map((col) => {
const style: Styles = {
width: formatCSSUnit(this.thWidthList[col.colKey] || col.width) || defaultColWidth,
};
if (col.minWidth) {
style.minWidth = formatCSSUnit(col.minWidth);
}
return <col key={col.colKey} style={style}></col>;
})}
</colgroup>
{renderColGroup()}
<TFoot
rowKey={this.rowKey}
v-slots={this.$slots}
Expand Down Expand Up @@ -458,29 +486,21 @@ export default defineComponent({
{this.isVirtual && <div class={this.virtualScrollClasses.cursor} style={virtualStyle} />}

<table ref="tableElmRef" class={this.tableElmClasses} style={this.tableElementStyles}>
<colgroup>
{columns.map((col) => {
const style: Styles = {
width: formatCSSUnit(this.thWidthList[col.colKey] || col.width) || defaultColWidth,
};
if (col.minWidth) {
style.minWidth = formatCSSUnit(col.minWidth);
}
return <col key={col.colKey} style={style}></col>;
})}
</colgroup>
<THead
v-slots={this.$slots}
isFixedHeader={this.isFixedHeader}
rowAndColFixedPosition={this.rowAndColFixedPosition}
isMultipleHeader={this.isMultipleHeader}
bordered={this.bordered}
spansAndLeafNodes={this.spansAndLeafNodes}
thList={this.thList}
thWidthList={this.thWidthList}
resizable={this.resizable}
columnResizeParams={this.columnResizeParams}
/>
{renderColGroup()}
{this.showHeader && (
<THead
v-slots={this.$slots}
isFixedHeader={this.isFixedHeader}
rowAndColFixedPosition={this.rowAndColFixedPosition}
isMultipleHeader={this.isMultipleHeader}
bordered={this.bordered}
spansAndLeafNodes={this.spansAndLeafNodes}
thList={this.thList}
thWidthList={this.thWidthList}
resizable={this.resizable}
columnResizeParams={this.columnResizeParams}
/>
)}
<TBody v-slots={this.$slots} {...tableBodyProps} />
<TFoot
v-slots={this.$slots}
Expand Down Expand Up @@ -527,14 +547,7 @@ export default defineComponent({
<div ref="tableRef" class={this.dynamicBaseTableClasses} style="position: relative">
{!!topContent && <div class={this.tableBaseClass.topContent}>{topContent}</div>}

{!!(this.isVirtual || this.headerAffixedTop) &&
(this.headerAffixedTop ? (
<Affix offsetTop={0} {...getAffixProps(this.headerAffixedTop)} onFixedChange={this.onFixedChange}>
{affixHeaderWithWrap}
</Affix>
) : (
this.isFixedHeader && affixHeaderWithWrap
))}
{renderAffixedHeader()}

{tableContent}

Expand All @@ -556,25 +569,7 @@ export default defineComponent({
{bottom}

{/* 吸底的滚动条 */}
{this.horizontalScrollAffixedBottom && (
<Affix
offsetBottom={0}
{...getAffixProps(this.horizontalScrollAffixedBottom)}
style={{ marginTop: `-${this.scrollbarWidth * 2}px` }}
>
<div
ref="horizontalScrollbarRef"
class={['scrollbar', this.tableBaseClass.obviousScrollbar]}
style={{
width: `${this.tableWidth}px`,
overflow: 'auto',
opacity: Number(this.showAffixFooter),
}}
>
<div style={{ width: `${this.tableElmWidth}px`, height: '5px' }}></div>
</div>
</Affix>
)}
{this.horizontalScrollAffixedBottom && renderAffixedHorizontalScrollbar()}

{/* 吸底的分页器 */}
{this.paginationAffixedBottom ? (
Expand Down
Loading

0 comments on commit 466033b

Please sign in to comment.