mirror of
https://github.com/Tencent/tmagic-editor.git
synced 2026-09-22 03:46:27 +00:00
141 lines
3.6 KiB
Vue
141 lines
3.6 KiB
Vue
<template>
|
||
<div class="m-form-box" :style="style">
|
||
<div class="m-box-body" :style="bodyHeight ? { height: `${bodyHeight}px` } : {}">
|
||
<TMagicScrollbar>
|
||
<Form
|
||
ref="form"
|
||
:size="size"
|
||
:disabled="disabled"
|
||
:config="config"
|
||
:init-values="values"
|
||
:parent-values="parentValues"
|
||
:label-width="labelWidth"
|
||
:label-position="labelPosition"
|
||
:inline="inline"
|
||
:prevent-submit-default="preventSubmitDefault"
|
||
:use-field-text-in-error="useFieldTextInError"
|
||
:extend-state="extendState"
|
||
:type-match-valid="typeMatchValid"
|
||
:validate-on-init="validateOnInit"
|
||
@change="changeHandler"
|
||
></Form>
|
||
<slot></slot>
|
||
</TMagicScrollbar>
|
||
</div>
|
||
|
||
<div class="dialog-footer" :style="`height: ${footerHeight}px`">
|
||
<div>
|
||
<slot name="left"></slot>
|
||
</div>
|
||
<div>
|
||
<slot name="footer">
|
||
<TMagicButton type="primary" :size="size" :disabled="disabled" :loading="saveFetch" @click="submitHandler">{{
|
||
confirmText
|
||
}}</TMagicButton>
|
||
</slot>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { computed, ref, watchEffect } from 'vue';
|
||
|
||
import { TMagicButton, TMagicScrollbar } from '@tmagic/design';
|
||
|
||
import Form from './Form.vue';
|
||
import type { ContainerChangeEventData, FormConfig, FormState, FormValue } from './schema';
|
||
|
||
defineOptions({
|
||
name: 'MFormBox',
|
||
});
|
||
|
||
const props = withDefaults(
|
||
defineProps<{
|
||
config?: FormConfig;
|
||
values?: Object;
|
||
parentValues?: Object;
|
||
width?: number;
|
||
height?: number;
|
||
labelWidth?: string;
|
||
/** 是否开启类型匹配校验 */
|
||
typeMatchValid?: boolean;
|
||
/** 透传给内部 `MForm`,初始化完成后是否立即校验(默认 `false`) */
|
||
validateOnInit?: boolean;
|
||
disabled?: boolean;
|
||
size?: 'small' | 'default' | 'large';
|
||
confirmText?: string;
|
||
inline?: boolean;
|
||
labelPosition?: string;
|
||
preventSubmitDefault?: boolean;
|
||
/** 透传给内部 `MForm`,控制表单校验失败时错误提示前缀是否使用字段的 text 文案 */
|
||
useFieldTextInError?: boolean;
|
||
extendState?: (_state: FormState) => Record<string, any> | Promise<Record<string, any>>;
|
||
}>(),
|
||
{
|
||
config: () => [],
|
||
values: () => ({}),
|
||
confirmText: '确定',
|
||
useFieldTextInError: true,
|
||
validateOnInit: false,
|
||
},
|
||
);
|
||
|
||
const emit = defineEmits<{
|
||
change: [v: any, eventData: ContainerChangeEventData];
|
||
submit: [v: any, eventData: ContainerChangeEventData];
|
||
error: [e: any];
|
||
}>();
|
||
|
||
const footerHeight = 60;
|
||
|
||
const style = computed(() => {
|
||
const style: { width?: string; height?: string } = {};
|
||
if (typeof props.width === 'number') {
|
||
style.width = `${props.width}px`;
|
||
}
|
||
if (typeof props.height === 'number') {
|
||
style.height = `${props.height}px`;
|
||
}
|
||
return style;
|
||
});
|
||
|
||
const form = ref<InstanceType<typeof Form>>();
|
||
const saveFetch = ref(false);
|
||
|
||
const bodyHeight = ref(0);
|
||
|
||
watchEffect(() => {
|
||
if (!props.height) {
|
||
return;
|
||
}
|
||
bodyHeight.value = props.height - footerHeight;
|
||
});
|
||
|
||
const submitHandler = async () => {
|
||
try {
|
||
const changeRecords = form.value?.changeRecords;
|
||
const values = await form.value?.submitForm();
|
||
emit('submit', values, { changeRecords });
|
||
} catch (e) {
|
||
emit('error', e);
|
||
}
|
||
};
|
||
|
||
const changeHandler = (value: FormValue, eventData: ContainerChangeEventData) => {
|
||
emit('change', value, eventData);
|
||
};
|
||
|
||
const show = () => {};
|
||
|
||
const hide = () => {};
|
||
|
||
defineExpose({
|
||
form,
|
||
saveFetch,
|
||
|
||
show,
|
||
hide,
|
||
});
|
||
</script>
|