fix(design,editro,element-plus-adapter,tdesign-vue-next-adapter): elememt-plus表单渲染失败

This commit is contained in:
roymondchen 2025-11-24 16:14:21 +08:00
parent 09dfaad2cc
commit 93640257e9
10 changed files with 160 additions and 48 deletions

View File

@ -27,7 +27,7 @@
</template>
<script setup lang="ts">
import { computed, ref, watchEffect } from 'vue';
import { computed, ref, useTemplateRef, watchEffect } from 'vue';
import { getDesignConfig } from './config';
import type { AutocompleteProps } from './types';
@ -58,13 +58,13 @@ const updateModelValue = (...args: any[]) => {
emit('update:modelValue', ...args);
};
const autocomplete = ref<any>();
const autocompleteRef = useTemplateRef<any>('autocomplete');
const input = ref<HTMLInputElement>();
const inputRef = ref<any>();
watchEffect(() => {
inputRef.value = autocomplete.value?.inputRef;
input.value = autocomplete.value?.inputRef.input;
inputRef.value = autocompleteRef.value?.inputRef;
input.value = autocompleteRef.value?.inputRef.input;
});
defineExpose({
@ -72,10 +72,10 @@ defineExpose({
input,
blur: () => {
autocomplete.value?.blur();
autocompleteRef.value?.blur();
},
focus: () => {
autocomplete.value?.focus();
autocompleteRef.value?.focus();
},
});
</script>

View File

@ -3,7 +3,11 @@
<template #label>
<slot name="label"></slot>
</template>
<slot></slot>
<template #default>
<slot></slot>
<div v-if="adapterType === 'element-plus' && extra" v-html="extra" class="m-form-tip"></div>
</template>
</component>
</template>
@ -23,5 +27,10 @@ const ui = getDesignConfig('components')?.formItem;
const uiComponent = ui?.component || 'el-form-item';
const uiProps = computed<FormItemProps>(() => ui?.props(props) || props);
const adapterType = getDesignConfig('adapterType');
const uiProps = computed<FormItemProps>(() => {
const { extra, ...rest } = ui?.props(props) || props;
return rest;
});
</script>

View File

@ -6,7 +6,6 @@ export type FieldSize = 'large' | 'default' | 'small';
export interface AutocompleteProps {
modelValue?: string;
placeholder?: string;
label?: string;
clearable?: boolean;
disabled?: boolean;
triggerOnFocus?: boolean;
@ -185,7 +184,7 @@ export interface FormItemProps {
labelWidth?: string | number;
rules?: any;
extra?: string;
labelPosition?: string;
labelPosition?: 'top' | 'left' | 'right';
}
export interface InputProps {

View File

@ -38,12 +38,29 @@
</template>
</component>
<div
:class="`tmagic-data-source-input-text el-input t-input t-size-${size?.[0]} el-input--${size}`"
@mouseup="mouseupHandler"
v-else
:class="{
'tmagic-data-source-input-text': true,
'el-input': adapterType === 'element-plus',
[`el-input--${size}`]: adapterType === 'element-plus',
't-input': adapterType === 'tdesign-vue-next',
[`t-size-${size?.[0]}`]: adapterType === 'tdesign-vue-next',
}"
@mouseup="mouseupHandler"
>
<div :class="`tmagic-data-source-input-text-wrapper el-input__wrapper ${isFocused ? ' is-focus' : ''}`">
<div class="el-input__inner t-input__inner">
<div
:class="{
'tmagic-data-source-input-text-wrapper': true,
'el-input__wrapper': adapterType === 'element-plus',
'is-focus': isFocused,
}"
>
<div
:class="{
'el-input__inner': adapterType === 'element-plus',
input__inner: adapterType === 'tdesign-vue-next',
}"
>
<template v-for="(item, index) in displayState">
<span :key="index" v-if="item.type === 'text'" style="margin-right: 2px">{{ item.value }}</span>
<TMagicTag :key="index" :size="size" v-if="item.type === 'var'">{{ item.value }}</TMagicTag>
@ -80,6 +97,8 @@ const emit = defineEmits<{
change: [value: string];
}>();
const adapterType = getDesignConfig('adapterType');
const { dataSourceService, propsService } = useServices();
const autocompleteRef = useTemplateRef<InstanceType<typeof TMagicAutocomplete>>('autocomplete');

View File

@ -1,27 +0,0 @@
<template>
<ElFormItem v-bind="itemProps">
<template #label>
<slot name="label"></slot>
</template>
<slot></slot>
<div v-if="extra" v-html="extra" class="m-form-tip"></div>
</ElFormItem>
</template>
<script setup lang="ts">
import { computed } from 'vue';
import { ElFormItem } from 'element-plus';
import { FormItemProps } from '@tmagic/design';
defineOptions({
name: 'TElAdapterFormItem',
});
const props = defineProps<FormItemProps>();
const itemProps = computed(() => {
const { extra, ...rest } = props;
return rest;
});
</script>

View File

@ -18,6 +18,7 @@ import {
ElDropdownItem,
ElDropdownMenu,
ElForm,
ElFormItem,
ElIcon,
ElInput,
ElInputNumber,
@ -90,7 +91,6 @@ import type {
UploadProps,
} from '@tmagic/design';
import FormItem from './FormItem.vue';
import Table from './Table.vue';
const adapter: DesignPluginOptions = {
@ -200,7 +200,7 @@ const adapter: DesignPluginOptions = {
},
formItem: {
component: FormItem as any,
component: ElFormItem as any,
props: (props: FormItemProps) => props,
},

View File

@ -0,0 +1,102 @@
<template>
<TAutoComplete
ref="autocomplete"
:model-value="modelValue"
:options="options"
:disabled="disabled"
:placeholder="placeholder"
:size="size === 'default' ? 'medium' : size"
:popupProps="{
trigger: props.triggerOnFocus ? 'focus' : 'hover',
}"
:filter="filterHandler"
@keypress="inputHandler"
@change="changeHandler"
@blur="blurHandler"
@focus="focusHandler"
@click="clickHandler"
@update:modelValue="updateModelValue"
>
<template #option="{ option }" v-if="$slots.default">
<slot name="default" :item="option"></slot>
</template>
<template #prepend v-if="$slots.prepend">
<slot name="prepend"></slot>
</template>
<template #append v-if="$slots.append">
<slot name="append"></slot>
</template>
<template #prefix v-if="$slots.prefix">
<slot name="prefix"></slot>
</template>
<template #suffix v-if="$slots.suffix">
<slot name="suffix"></slot>
</template>
</TAutoComplete>
</template>
<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { AutoComplete as TAutoComplete, type AutoCompleteOption } from 'tdesign-vue-next';
import type { AutocompleteProps } from '@tmagic/design';
defineOptions({
name: 'TTDesignAdapterAutoComplete',
});
const emit = defineEmits(['change', 'input', 'blur', 'focus', 'click', 'update:modelValue']);
const props = defineProps<AutocompleteProps>();
const options = ref<any[]>([]);
onMounted(() => {
if (typeof props.fetchSuggestions === 'function') {
props.fetchSuggestions('', (data: any[]) => {
options.value = data;
});
} else if (Array.isArray(props.fetchSuggestions)) {
options.value = props.fetchSuggestions;
}
});
const filterHandler = (keyword: string, _option: AutoCompleteOption) => {
if (typeof props.fetchSuggestions === 'function') {
props.fetchSuggestions(keyword, (data: any[]) => {
options.value = data;
});
}
return true;
};
const changeHandler = (...args: any[]) => {
emit('change', ...args);
};
const inputHandler = (...args: any[]) => {
emit('input', ...args);
};
const blurHandler = (...args: any[]) => {
emit('blur', ...args);
};
const focusHandler = (...args: any[]) => {
emit('focus', ...args);
};
const clickHandler = (...args: any[]) => {
emit('click', ...args);
};
const updateModelValue = (...args: any[]) => {
emit('update:modelValue', ...args);
};
defineExpose({
blur: () => {},
focus: () => {},
});
</script>

View File

@ -35,6 +35,7 @@ import {
} from 'tdesign-vue-next';
import type {
AutocompleteProps,
BadgeProps,
ButtonProps,
CardProps,
@ -75,6 +76,7 @@ import type {
UploadProps,
} from '@tmagic/design';
import AutoComplete from './AutoComplete.vue';
import Checkbox from './Checkbox.vue';
import DatePicker from './DatePicker.vue';
import Dialog from './Dialog.vue';
@ -168,6 +170,10 @@ const adapter: any = {
},
},
components: {
autocomplete: {
component: AutoComplete,
props: (props: AutocompleteProps) => props,
},
badge: {
component: TBadge,
props: (props: BadgeProps) => ({
@ -348,7 +354,7 @@ const adapter: any = {
labelWidth: props.labelWidth,
name: props.prop,
rules: props.rules,
help: props.extra,
help: () => h('div', { innerHTML: props.extra }),
labelAlign: props.labelPosition,
}),
},

View File

@ -17,7 +17,6 @@
*/
import { createApp } from 'vue';
import * as monaco from 'monaco-editor';
import EditorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
import CssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker';
import HtmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker';
@ -51,8 +50,6 @@ globalThis.MonacoEnvironment = {
},
};
monaco.languages.typescript.typescriptDefaults.setEagerModelSync(true);
const adpter = sessionStorage.getItem('tmagic-playground-ui-adapter') || 'element-plus';
let adpterModule;

View File

@ -26,7 +26,14 @@
</template>
</TMagicEditor>
<TMagicDialog v-model="previewVisible" destroy-on-close class="pre-viewer" title="预览" :width="stageRect?.width">
<TMagicDialog
v-model="previewVisible"
close-onClick-modal
destroy-on-close
class="pre-viewer"
title="预览"
:width="stageRect?.width"
>
<iframe
v-if="previewVisible"
ref="iframe"