Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(table): expand-on-row-click and select-on-row-click conflict #3260

Merged
merged 9 commits into from
Aug 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/_common
Submodule _common updated 1 files
+132 −20 js/table/tree-store.ts
77 changes: 48 additions & 29 deletions src/table/_example/tree.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
</t-checkbox>
</div>
<br />
<!-- 第一列展开树结点,缩进为 24px,子节点字段 childrenKey 默认为 children -->
<!-- !!! 树形结构 EnhancedTable 才支持,普通 Table 不支持 !!! -->
<!-- Ref: table.value.dataSource 查看树形结构平铺数据,获取属性结构使用 table.value.getTreeNode() -->
<!-- 第一列展开树结点,缩进为 24px,子节点字段 childrenKey 默认为 children -->
<!-- v-model:displayColumns="displayColumns" used to control displayed columns -->
<!-- v-model:expandedTreeNodes is not required. you can control expanded tree node by expandedTreeNodes -->
<t-enhanced-table
ref="table"
ref="tableRef"
v-model:expandedTreeNodes="expandedTreeNodes"
row-key="key"
drag-sort="row-handler"
:data="data"
Expand All @@ -38,14 +40,15 @@
@page-change="onPageChange"
@abnormal-drag-sort="onAbnormalDragSort"
@drag-sort="onDragSort"
@tree-expand-change="onTreeExpandChange"
@expanded-tree-nodes-change="onExpandedTreeNodesChange"
></t-enhanced-table>
<!-- @tree-expand-change="onTreeExpandChange" -->

<!-- 第二列展开树结点,缩进为 12px,示例代码有效,勿删 -->
<!-- indent 定义缩进距离 -->
<!-- 如果子结点字段不是 'children',可以使用 childrenKey 定义字段别名,如 `:tree="{ childrenKey: 'list' }"` -->
<!-- <t-enhanced-table
ref="table"
ref="tableRef"
rowKey="key"
:pagination="defaultPagination"
:data="data"
Expand Down Expand Up @@ -130,20 +133,24 @@ function getData(currentPage = 1) {
return data;
}

const table = ref(null);
const tableRef = ref(null);
const data = ref(getData());
const lazyLoadingData = ref(null);

// 非必须,如果不传,表格有内置树形节点展开逻辑
const expandedTreeNodes = ref([]);

const treeConfig = reactive({ childrenKey: 'list', treeNodeColumnIndex: 2, indent: 25 });

// 重置数据和展开节点
const resetData = () => {
// 需要更新数据地址空间
const newData = getData();
// 直接赋值,仅在 keys 发生变化时会重置;无论什么情况都希望更新数据,请使用 table.value.resetData(newData)
// data.value = newData;
table.value.resetData(newData);
// 方式一
data.value = newData;
expandedTreeNodes.value = [];

console.log(table.value);
// 方式二
// tableRef.value.resetData(newData);
};

const onEditClick = (row) => {
Expand All @@ -153,25 +160,29 @@ const onEditClick = (row) => {
type: 'Symbol',
default: 'undefined',
};
table.value.setData(row.key, newData);
tableRef.value.setData(row.key, newData);
MessagePlugin.success('数据已更新');
};

const onDeleteConfirm = (row) => {
table.value.remove(row.key);
// 移除当前节点及其所有子节点
tableRef.value.remove(row.key);

// 仅移除所有子节点
// tableRef.value.removeChildren(row.key);
MessagePlugin.success('删除成功');
};

const onLookUp = (row) => {
const allRowData = table.value.getData(row.key);
const allRowData = tableRef.value.getData(row.key);
const message = '当前行全部数据,包含节点路径、父节点、子节点、是否展开、是否禁用等';
MessagePlugin.success(`打开控制台查看${message}`);
console.log(`${message}:`, allRowData);
};

const appendTo = (row) => {
const randomKey1 = Math.round(Math.random() * Math.random() * 1000) + 10000;
table.value.appendTo(row.key, {
tableRef.value.appendTo(row.key, {
id: randomKey1,
key: `申请人 ${randomKey1} 号`,
platform: '电子签署',
Expand All @@ -187,7 +198,7 @@ function appendMultipleDataTo(row) {
const randomKey1 = Math.round(Math.random() * Math.random() * 1000) + 10000;
const randomKey2 = Math.round(Math.random() * Math.random() * 1000) + 10000;
const randomKey3 = Math.round(Math.random() * Math.random() * 1000) + 10000;
const newData = [
const appendList = [
{
id: randomKey1,
key: `申请人 ${randomKey1} 号`,
Expand All @@ -199,7 +210,6 @@ function appendMultipleDataTo(row) {
key: `申请人 ${randomKey2} 号`,
platform: '纸质签署',
type: 'Number',
list: true,
},
{
id: randomKey3,
Expand All @@ -209,14 +219,14 @@ function appendMultipleDataTo(row) {
list: true,
},
];
table.value.appendTo(row?.key, newData);
tableRef.value.appendTo(row?.key, appendList);
MessagePlugin.success(`已插入子节点申请人 ${randomKey1} 和 ${randomKey2} 号,请展开查看`);
}

// 当前节点之前,新增兄弟节前
const insertBefore = (row) => {
const randomKey = Math.round(Math.random() * Math.random() * 1000) + 10000;
table.value.insertBefore(row.key, {
tableRef.value.insertBefore(row.key, {
id: randomKey,
key: `申请人 ${randomKey} 号`,
platform: '纸质签署',
Expand All @@ -228,7 +238,7 @@ const insertBefore = (row) => {
// 当前节点之后,新增兄弟节前
const insertAfter = (row) => {
const randomKey = Math.round(Math.random() * Math.random() * 1000) + 10000;
table.value.insertAfter(row.key, {
tableRef.value.insertAfter(row.key, {
id: randomKey,
key: `申请人 ${randomKey} 号`,
platform: '纸质签署',
Expand Down Expand Up @@ -319,17 +329,17 @@ const onRowToggle = () => {
const rowIds = ['申请人 1_1 号', '申请人 2_1 号', '申请人 3_1 号', '申请人 4_1 号'];
rowIds.forEach((id) => {
// getData 参数为行唯一标识,lodash.get(row, rowKey)
const rowData = table.value.getData(id);
table.value.toggleExpandData(rowData);
const rowData = tableRef.value.getData(id);
tableRef.value.toggleExpandData(rowData);
// 或者
// table.value.toggleExpandData({ rowIndex: rowData.rowIndex, row: rowData.row });
// tableRef.value.toggleExpandData({ rowIndex: rowData.rowIndex, row: rowData.row });
});
};

const customTreeExpandAndFoldIcon = ref(false);

const treeExpandAndFoldIconRender = (h, { type, row }) => {
if (lazyLoadingData.value && lazyLoadingData.value.id === row?.id) {
if (lazyLoadingData.value && lazyLoadingData.value.key === row?.key) {
return <Loading size="14px" />;
}
return type === 'expand' ? <ChevronRightIcon /> : <ChevronDownIcon />;
Expand All @@ -338,26 +348,28 @@ const treeExpandAndFoldIconRender = (h, { type, row }) => {
// 懒加载图标渲染
const lazyLoadingTreeIconRender = (h, params) => {
const { type, row } = params;
if (lazyLoadingData.value && lazyLoadingData.value.id === row?.id) {
if (lazyLoadingData.value && lazyLoadingData.value.key === row?.key) {
return <Loading size="14px" />;
}
return type === 'expand' ? <AddRectangleIcon /> : <MinusRectangleIcon />;
};

// 默认展开全部。示例代码有效,勿删
// onMounted(() => {
// table.value.expandAll();
// tableRef.value.expandAll();
// });

const getTreeNode = () => {
const treeData = table.value.getTreeNode();
// 查看树形结构平铺数据
// tableRef.value.dataSource
const treeData = tableRef.value.getTreeNode();
console.log(treeData);
MessagePlugin.success('树形结构获取成功,请打开控制台查看');
};

const onExpandAllToggle = () => {
expandAll.value = !expandAll.value;
expandAll.value ? table.value.expandAll() : table.value.foldAll();
expandAll.value ? tableRef.value.expandAll() : tableRef.value.foldAll();
};

const appendToRoot = () => {
Expand All @@ -375,7 +387,7 @@ const appendToRoot = () => {
description: '数据源',
};
// data.value.push(newData);
table.value.appendTo('', newData);
tableRef.value.appendTo('', newData);

// 同时添加多个元素,示例代码有效勿删
// appendMultipleDataTo();
Expand All @@ -389,6 +401,13 @@ const onAbnormalDragSort = (params) => {
}
};

const onExpandedTreeNodesChange = (expandedTreeNodes, context) => {
console.log(expandedTreeNodes, context);
// 全选不需要处理;仅处理懒加载
if (!context.rowState) return;
onTreeExpandChange(context);
};

const onTreeExpandChange = (context) => {
console.log(context.rowState.expanded ? '展开' : '收起', context);
/**
Expand Down
14 changes: 13 additions & 1 deletion src/table/enhanced-table-props.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ export default {
beforeDragSort: {
type: Function as PropType<TdEnhancedTableProps['beforeDragSort']>,
},
/** 展开的树形节点。非必须。在需要自由控制展开的树形节点时使用。其他场景无需设置,表格组件有内置展开逻辑 */
expandedTreeNodes: {
type: Array as PropType<TdEnhancedTableProps['expandedTreeNodes']>,
default: undefined as TdEnhancedTableProps['expandedTreeNodes'],
},
/** 展开的树形节点。非必须。在需要自由控制展开的树形节点时使用。其他场景无需设置,表格组件有内置展开逻辑,非受控属性 */
defaultExpandedTreeNodes: {
type: Array as PropType<TdEnhancedTableProps['defaultExpandedTreeNodes']>,
default: (): TdEnhancedTableProps['defaultExpandedTreeNodes'] => [],
},
/** 树形结构相关配置。具体属性文档查看 `TableTreeConfig` 相关描述 */
tree: {
type: Object as PropType<TdEnhancedTableProps['tree']>,
Expand All @@ -22,6 +32,8 @@ export default {
},
/** 异常拖拽排序时触发,如:树形结构中,非同层级之间的交换。`context.code` 指交换异常错误码,固定值;`context.reason` 指交换异常的原因 */
onAbnormalDragSort: Function as PropType<TdEnhancedTableProps['onAbnormalDragSort']>,
/** 树形结构,用户操作引起节点展开或收起时触发,代码操作不会触发 */
/** 树形结构,展开的树节点发生变化时触发,泛型 T 指表格数据类型 */
onExpandedTreeNodesChange: Function as PropType<TdEnhancedTableProps['onExpandedTreeNodesChange']>,
/** 已废弃。树形结构,用户操作引起节点展开或收起时触发。请更为使用 `onExpandedTreeNodesChange` */
onTreeExpandChange: Function as PropType<TdEnhancedTableProps['onTreeExpandChange']>,
};
54 changes: 25 additions & 29 deletions src/table/hooks/useTreeData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import {
AddRectangleIcon as TdAddRectangleIcon,
MinusRectangleIcon as TdMinusRectangleIcon,
} from 'tdesign-icons-vue-next';
import cloneDeep from 'lodash/cloneDeep';
import get from 'lodash/get';
import TableTreeStore, { SwapParams } from '../../_common/js/table/tree-store';
import {
Expand All @@ -19,6 +18,7 @@ import { renderCell } from '../tr';
import { useConfig } from '../../hooks/useConfig';
import { useGlobalIcon } from '../../hooks/useGlobalIcon';
import { useTNodeDefault } from '../../hooks';
import useTreeDataExpand from './useTreeDataExpand';

export default function useTreeData(props: TdEnhancedTableProps, context: SetupContext) {
const { data, columns } = toRefs(props);
Expand All @@ -39,6 +39,11 @@ export default function useTreeData(props: TdEnhancedTableProps, context: SetupC
childrenKey: props.tree?.childrenKey || 'children',
}));

const { tExpandedTreeNode, expandAll, foldAll, updateExpandOnDataChange, onExpandFoldIconClick } = useTreeDataExpand(
props,
{ store, dataSource, rowDataKeys },
);

const checkedColumn = computed(() => columns.value.find((col) => col.colKey === 'row-select'));

watch(checkedColumn, (column) => {
Expand All @@ -64,18 +69,14 @@ export default function useTreeData(props: TdEnhancedTableProps, context: SetupC
});
};

const uniqueKeys = computed(() => store.value?.getAllUniqueKeys(data.value, rowDataKeys.value)?.join() || '');

watch(
[uniqueKeys],
[data],
() => {
if (!data.value) return;
// 如果没有树形解构,则不需要相关逻辑
if (!props.tree) {
if (props.tree) {
resetData(data.value);
} else {
dataSource.value = data.value;
return;
}
resetData(data.value);
},
{ immediate: true },
);
Expand All @@ -100,12 +101,12 @@ export default function useTreeData(props: TdEnhancedTableProps, context: SetupC
);

function resetData(data: TableRowData[]) {
let newVal = cloneDeep(data);
store.value.initialTreeStore(newVal, props.columns, rowDataKeys.value);
if (props.tree?.defaultExpandAll) {
newVal = store.value.expandAll(newVal, rowDataKeys.value);
store.value.initialTreeStore(data, props.columns, rowDataKeys.value);
if (tExpandedTreeNode.value?.length) {
updateExpandOnDataChange(data);
} else {
dataSource.value = [...data];
}
dataSource.value = newVal;
}

function getTreeNodeStyle(level: number) {
Expand Down Expand Up @@ -169,7 +170,7 @@ export default function useTreeData(props: TdEnhancedTableProps, context: SetupC
<span
class={tableTreeClasses.icon}
onClick={(e: MouseEvent) => {
toggleExpandData(p, 'expand-fold-icon');
onExpandFoldIconClick(p, 'expand-fold-icon');
e.stopPropagation();
}}
>
Expand Down Expand Up @@ -224,6 +225,14 @@ export default function useTreeData(props: TdEnhancedTableProps, context: SetupC
dataSource.value = [...store.value.remove(key, dataSource.value, rowDataKeys.value)];
}

/**
* 移除子节点
* @param key 行唯一标识
*/
function removeChildren(key: TableRowValue) {
dataSource.value = [...store.value.removeChildren(key, dataSource.value, rowDataKeys.value)];
}

/**
* 对外暴露的组件实例方法,为当前节点添加子节点,默认添加到最后一个节点
* @param key 当前节点唯一标识,值为空,则表示给根节点添加元素
Expand Down Expand Up @@ -252,20 +261,6 @@ export default function useTreeData(props: TdEnhancedTableProps, context: SetupC
dataSource.value = [...store.value.insertBefore(rowValue, newData, dataSource.value, rowDataKeys.value)];
}

/**
* 对外暴露的组件实例方法,展开所有节点
*/
function expandAll() {
dataSource.value = [...store.value.expandAll(dataSource.value, rowDataKeys.value)];
}

/**
* 对外暴露的组件实例方法,收起所有节点
*/
function foldAll() {
dataSource.value = [...store.value.foldAll(dataSource.value, rowDataKeys.value)];
}

/**
* 对外暴露的组件实例方法,交换行数据
*/
Expand Down Expand Up @@ -305,6 +300,7 @@ export default function useTreeData(props: TdEnhancedTableProps, context: SetupC
setData,
getData,
remove,
removeChildren,
appendTo,
insertAfter,
insertBefore,
Expand Down
Loading
Loading