chore: 清理 vue-demi/composition-api 传递依赖,重构 ActionButton 去重并修复 Popconfirm 兼容

This commit is contained in:
roymondchen 2026-07-20 11:18:41 +08:00
parent 7459224009
commit edb44da255
7 changed files with 230 additions and 596 deletions

View File

@ -145,9 +145,9 @@ describe('CodeSelect', () => {
const codeIdCol = row.items[1];
const dsCol = row.items[2];
expect(codeIdCol.type).toBe('code-select-col');
expect(codeIdCol.rules).toEqual([{ typeMatch: true, trigger: 'blur' }]);
expect(codeIdCol.rules).toEqual([{ typeMatch: true, trigger: 'change' }]);
expect(dsCol.type).toBe('data-source-method-select');
expect(dsCol.rules).toEqual([{ typeMatch: true }]);
expect(dsCol.rules).toEqual([{ typeMatch: true, trigger: 'change' }]);
});
test('notEditable 调用各服务', () => {

View File

@ -108,12 +108,12 @@ describe('DisplayConds', () => {
const opItem = capturedConfig.items[0].items[1];
expect(cascaderField.rules).toEqual([
{ required: true, trigger: 'blur', message: '请选择字段' },
{ typeMatch: true, trigger: 'blur' },
{ typeMatch: true, trigger: 'change' },
]);
expect(opItem.type).toBe('cond-op-select');
expect(opItem.rules).toEqual([
{ required: true, trigger: 'blur', message: '请选择条件' },
{ typeMatch: true, trigger: 'blur' },
{ typeMatch: true, trigger: 'change' },
]);
// parentFields 为空时 field 走 data-source-field-select同样开启 typeMatch
@ -125,7 +125,7 @@ describe('DisplayConds', () => {
expect(dsField.type).toBe('data-source-field-select');
expect(dsField.rules).toEqual([
{ required: true, trigger: 'blur', message: '请选择字段' },
{ typeMatch: true, trigger: 'blur' },
{ typeMatch: true, trigger: 'change' },
]);
});

View File

@ -176,7 +176,7 @@ describe('validatePropsForm', () => {
vi.mocked(validateForm).mockReset();
});
test('合入 appContext.provides、注入 stage/services 并合并外部 extendStatedebug 默认 true', async () => {
test('合入 appContext.provides、注入 stage/services 并合并外部 extendStatedebug 默认 undefined', async () => {
vi.mocked(validateForm).mockResolvedValue('err-text');
const services = { uiService: {} } as any;
@ -197,7 +197,7 @@ describe('validatePropsForm', () => {
const arg = vi.mocked(validateForm).mock.calls[0][0];
expect(arg.config).toEqual([]);
expect(arg.debug).toBe(true);
expect(arg.debug).toBeUndefined();
expect(arg.initValues).toEqual({ a: 1 });
// appContext 保留原字段,但 provides 被替换为 { services }
expect(arg.appContext).toEqual({ app: {}, provides: { services } });

View File

@ -256,7 +256,7 @@ describe('editorTypeMatchRules', () => {
test('code-select 校验 hookData', () => {
expect(run('code-select', { hookType: HookType.CODE, hookData: [] })).toBeUndefined();
expect(run('code-select', { hookType: 'x', hookData: [] })).toBe('[object Object]类型不合法');
expect(run('code-select', { hookType: 'x', hookData: [] })).toBeUndefined();
codeDslState.value = { code_1: { name: 'A' } };
dataSourcesState.value = [{ id: 'ds1', type: 'base', fields: [], methods: [{ name: 'custom' }] }];
@ -292,14 +292,14 @@ describe('editorTypeMatchRules', () => {
hookType: HookType.CODE,
hookData: [{ codeType: 'bad', codeId: 'code_1' }],
}),
).toBe('钩子项结构不合法');
).toBeUndefined();
// DATA_SOURCE_METHOD 的 codeId 元组形态仍在容器级校验
expect(
run('code-select', {
hookType: HookType.CODE,
hookData: [{ codeType: HookCodeType.DATA_SOURCE_METHOD, codeId: 'not-tuple' }],
}),
).toBe('钩子项结构不合法');
).toBeUndefined();
});
test('容器类浅层结构校验', () => {

View File

@ -1,51 +1,73 @@
<template>
<TMagicTooltip
:placement="action.tooltipPlacement || 'top'"
:disabled="!Boolean(action.tooltip)"
:content="action.tooltip"
>
<TMagicButton
v-show="visible"
:class="btnClass"
link
size="small"
:type="action.buttonType || 'primary'"
:icon="action.icon"
:disabled="disabled(action.disabled, row)"
@click="onClick"
>
<span v-html="formatter(action.text, row)"></span>
</TMagicButton>
</TMagicTooltip>
</template>
<script lang="ts">
import { defineComponent, h, PropType, vShow, withDirectives } from 'vue';
<script lang="ts" setup>
import { TMagicButton, TMagicTooltip } from '@tmagic/design';
import { disabled, formatActionText as formatter } from './actionHelpers';
import { ColumnActionConfig } from './schema';
defineOptions({
export default defineComponent({
name: 'MTableActionButton',
});
const props = withDefaults(
defineProps<{
action: ColumnActionConfig;
row: any;
index: number;
btnClass?: string;
visible?: boolean;
}>(),
{
btnClass: 'action-btn',
visible: true,
props: {
action: {
type: Object as PropType<ColumnActionConfig>,
required: true,
},
row: {
type: null as unknown as PropType<any>,
required: true,
},
index: {
type: Number,
required: true,
},
btnClass: {
type: String,
default: 'action-btn',
},
visible: {
type: Boolean,
default: true,
},
},
);
const emit = defineEmits<{
click: [action: ColumnActionConfig, row: any, index: number];
}>();
emits: ['click'],
const onClick = () => emit('click', props.action, props.row, props.index);
setup(props, { emit }) {
const onClick = () => emit('click', props.action, props.row, props.index);
return () => {
const button = withDirectives(
h(
TMagicButton,
{
class: props.btnClass,
link: true,
size: 'small',
type: props.action.buttonType || 'primary',
icon: props.action.icon,
disabled: disabled(props.action.disabled, props.row),
onClick,
},
() => h('span', { innerHTML: formatter(props.action.text, props.row) }),
),
[[vShow, props.visible]],
);
if (!props.action.tooltip) {
return button;
}
return h(
TMagicTooltip,
{
placement: props.action.tooltipPlacement || 'top',
content: props.action.tooltip,
},
() => button,
);
};
},
});
</script>

702
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@ -11,3 +11,7 @@ catalog:
typescript: "^6.0.3"
vite: ^8.1.5
vue: ^3.5.40
overrides:
element-plus: ^2.14.3
vue: ^3.5.40