perf: 尝试优化table action

pull/170/head^2
xingyu4j 2025-07-09 17:48:49 +08:00
parent bfd3a209f8
commit 61a874f700
1 changed files with 36 additions and 42 deletions

View File

@ -60,39 +60,14 @@ function isIfShow(action: ActionItem): boolean {
/** 处理按钮 actions */ /** 处理按钮 actions */
const getActions = computed(() => { const getActions = computed(() => {
return (props.actions || []) return (props.actions || []).filter((action: ActionItem) => isIfShow(action));
.filter((action: ActionItem) => isIfShow(action))
.map((action: ActionItem) => {
const { popConfirm } = action;
return {
type: action.type || 'link',
...action,
...popConfirm,
onConfirm: popConfirm?.confirm,
onCancel: popConfirm?.cancel,
enable: !!popConfirm,
};
});
}); });
/** 处理下拉菜单 actions */ /** 处理下拉菜单 actions */
const getDropdownList = computed(() => { const getDropdownList = computed(() => {
return (props.dropDownActions || []) return (props.dropDownActions || []).filter((action: ActionItem) =>
.filter((action: ActionItem) => isIfShow(action)) isIfShow(action),
.map((action: ActionItem, index: number) => { );
const { label, popConfirm } = action;
const processedAction = { ...action };
delete processedAction.icon;
return {
...processedAction,
...popConfirm,
onConfirm: popConfirm?.confirm,
onCancel: popConfirm?.cancel,
text: label,
divider:
index < props.dropDownActions.length - 1 ? props.divider : false,
};
});
}); });
/** Space 组件的 size */ /** Space 组件的 size */
@ -103,18 +78,27 @@ const spaceSize = computed(() => {
}); });
/** 获取 PopConfirm 属性 */ /** 获取 PopConfirm 属性 */
function getPopConfirmProps(attrs: PopConfirm) { function getPopConfirmProps(popConfirm: PopConfirm) {
const originAttrs: any = { ...attrs }; if (!popConfirm) return {};
delete originAttrs.icon;
if (attrs.confirm && isFunction(attrs.confirm)) { const attrs: Record<string, any> = {};
originAttrs.onConfirm = attrs.confirm;
delete originAttrs.confirm; //
Object.keys(popConfirm).forEach((key) => {
if (key !== 'confirm' && key !== 'cancel' && key !== 'icon') {
attrs[key] = popConfirm[key as keyof PopConfirm];
} }
if (attrs.cancel && isFunction(attrs.cancel)) { });
originAttrs.onCancel = attrs.cancel;
delete originAttrs.cancel; //
if (popConfirm.confirm && isFunction(popConfirm.confirm)) {
attrs.onConfirm = popConfirm.confirm;
} }
return originAttrs; if (popConfirm.cancel && isFunction(popConfirm.cancel)) {
attrs.onCancel = popConfirm.cancel;
}
return attrs;
} }
/** 获取 Button 属性 */ /** 获取 Button 属性 */
@ -146,6 +130,13 @@ function handleMenuClick(e: any) {
function getActionKey(action: ActionItem, index: number) { function getActionKey(action: ActionItem, index: number) {
return `${action.label || ''}-${action.type || ''}-${index}`; return `${action.label || ''}-${action.type || ''}-${index}`;
} }
/** 处理按钮点击 */
function handleButtonClick(action: ActionItem) {
if (action.onClick && isFunction(action.onClick)) {
action.onClick();
}
}
</script> </script>
<template> <template>
@ -172,7 +163,10 @@ function getActionKey(action: ActionItem, index: number) {
</Tooltip> </Tooltip>
</Popconfirm> </Popconfirm>
<Tooltip v-else v-bind="getTooltipProps(action.tooltip)"> <Tooltip v-else v-bind="getTooltipProps(action.tooltip)">
<Button v-bind="getButtonProps(action)" @click="action.onClick"> <Button
v-bind="getButtonProps(action)"
@click="handleButtonClick(action)"
>
<template v-if="action.icon" #icon> <template v-if="action.icon" #icon>
<IconifyIcon :icon="action.icon" /> <IconifyIcon :icon="action.icon" />
</template> </template>
@ -184,7 +178,7 @@ function getActionKey(action: ActionItem, index: number) {
<Dropdown v-if="getDropdownList.length > 0" :trigger="['hover']"> <Dropdown v-if="getDropdownList.length > 0" :trigger="['hover']">
<slot name="more"> <slot name="more">
<Button :type="getDropdownList[0]?.type"> <Button type="link">
<template #icon> <template #icon>
{{ $t('page.action.more') }} {{ $t('page.action.more') }}
<IconifyIcon icon="lucide:ellipsis-vertical" /> <IconifyIcon icon="lucide:ellipsis-vertical" />
@ -213,7 +207,7 @@ function getActionKey(action: ActionItem, index: number) {
> >
<IconifyIcon v-if="action.icon" :icon="action.icon" /> <IconifyIcon v-if="action.icon" :icon="action.icon" />
<span :class="action.icon ? 'ml-1' : ''"> <span :class="action.icon ? 'ml-1' : ''">
{{ action.text }} {{ action.label }}
</span> </span>
</div> </div>
</Popconfirm> </Popconfirm>