* feat: 增加Prompt组件 类似于Element UI组件库的MessageBox Prompt组件 * fix: #2976 * refactor: 对appendSchemaByField函数的通用操作进行整理
This commit is contained in:
parent
248f9d5e81
commit
7b26c5994c
|
|
@ -229,16 +229,11 @@ export function useFormEvents({
|
||||||
const _schemaList = isObject(schema) ? [schema as FormSchema] : (schema as FormSchema[]);
|
const _schemaList = isObject(schema) ? [schema as FormSchema] : (schema as FormSchema[]);
|
||||||
if (!prefixField || index === -1 || first) {
|
if (!prefixField || index === -1 || first) {
|
||||||
first ? schemaList.unshift(..._schemaList) : schemaList.push(..._schemaList);
|
first ? schemaList.unshift(..._schemaList) : schemaList.push(..._schemaList);
|
||||||
schemaRef.value = schemaList;
|
} else if (index !== -1) {
|
||||||
_setDefaultValue(schema);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (index !== -1) {
|
|
||||||
schemaList.splice(index + 1, 0, ..._schemaList);
|
schemaList.splice(index + 1, 0, ..._schemaList);
|
||||||
}
|
}
|
||||||
_setDefaultValue(schema);
|
|
||||||
|
|
||||||
schemaRef.value = schemaList;
|
schemaRef.value = schemaList;
|
||||||
|
_setDefaultValue(schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function resetSchema(data: Partial<FormSchema> | Partial<FormSchema>[]) {
|
async function resetSchema(data: Partial<FormSchema> | Partial<FormSchema>[]) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
<template>
|
||||||
|
<Modal
|
||||||
|
v-model:visible="visible"
|
||||||
|
:title="title"
|
||||||
|
@ok="handleSubmit"
|
||||||
|
:destroyOnClose="true"
|
||||||
|
:width="width || '500px'"
|
||||||
|
okText="确定"
|
||||||
|
cancelText="取消"
|
||||||
|
>
|
||||||
|
<div class="pt-5 pr-3px">
|
||||||
|
<BasicForm @register="register" />
|
||||||
|
</div>
|
||||||
|
</Modal>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { Modal } from 'ant-design-vue';
|
||||||
|
import { FormSchema } from '/@/components/Form';
|
||||||
|
import { BasicForm, useForm } from '/@/components/Form/index';
|
||||||
|
|
||||||
|
const visible = ref<boolean>(true);
|
||||||
|
const props = defineProps<{
|
||||||
|
title: string;
|
||||||
|
addFormSchemas: FormSchema[];
|
||||||
|
onOK?: Fn;
|
||||||
|
width?: string;
|
||||||
|
labelWidth?: number;
|
||||||
|
layout?: 'horizontal' | 'vertical' | 'inline';
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const [register, { validate }] = useForm({
|
||||||
|
schemas: props.addFormSchemas,
|
||||||
|
showActionButtonGroup: false,
|
||||||
|
labelWidth: props.labelWidth || 80,
|
||||||
|
layout: props.layout || 'horizontal',
|
||||||
|
});
|
||||||
|
|
||||||
|
async function handleSubmit() {
|
||||||
|
const row = await validate();
|
||||||
|
if (props.onOK) {
|
||||||
|
await props.onOK(row.txt);
|
||||||
|
}
|
||||||
|
visible.value = false;
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
import { createVNode, VNode, defineComponent, h, render, reactive } from 'vue';
|
||||||
|
import { PromptProps, genFormSchemas } from './state';
|
||||||
|
import Dialog from './dialog.vue';
|
||||||
|
|
||||||
|
export function createPrompt(props: PromptProps) {
|
||||||
|
let vm: Nullable<VNode> = null;
|
||||||
|
const data = reactive({
|
||||||
|
...props,
|
||||||
|
addFormSchemas: genFormSchemas({
|
||||||
|
label: props.label,
|
||||||
|
required: props.required,
|
||||||
|
inputType: props.inputType,
|
||||||
|
defaultValue: props.defaultValue,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
const DialogWrap = defineComponent({
|
||||||
|
render() {
|
||||||
|
return h(Dialog, { ...data } as any);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
vm = createVNode(DialogWrap);
|
||||||
|
|
||||||
|
render(vm, document.createElement('div'));
|
||||||
|
|
||||||
|
function close() {
|
||||||
|
if (vm?.el && vm.el.parentNode) {
|
||||||
|
vm.el.parentNode.removeChild(vm.el);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
vm,
|
||||||
|
close,
|
||||||
|
get $el() {
|
||||||
|
return vm?.el as HTMLElement;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
import { FormSchema } from '/@/components/Form';
|
||||||
|
|
||||||
|
type InputType = 'InputTextArea' | 'InputNumber' | 'Input';
|
||||||
|
export interface PromptProps {
|
||||||
|
title: string;
|
||||||
|
label?: string;
|
||||||
|
required?: boolean;
|
||||||
|
onOK?: Fn;
|
||||||
|
inputType?: InputType;
|
||||||
|
labelWidth?: number;
|
||||||
|
width?: string;
|
||||||
|
layout?: 'horizontal' | 'vertical' | 'inline';
|
||||||
|
defaultValue?: string | number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface genFormSchemasProps {
|
||||||
|
label?: string;
|
||||||
|
required?: boolean;
|
||||||
|
inputType?: InputType;
|
||||||
|
defaultValue?: string | number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const inputTypeMap: {
|
||||||
|
[key in InputType]: {
|
||||||
|
colProps: { span: number; offset?: number };
|
||||||
|
componentProps: FormSchema['componentProps'];
|
||||||
|
};
|
||||||
|
} = {
|
||||||
|
InputTextArea: {
|
||||||
|
colProps: { span: 23 },
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入内容',
|
||||||
|
autoSize: { minRows: 2, maxRows: 6 },
|
||||||
|
maxlength: 255,
|
||||||
|
showCount: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
InputNumber: {
|
||||||
|
colProps: { span: 20, offset: 2 },
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入数字',
|
||||||
|
min: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Input: {
|
||||||
|
colProps: { span: 20, offset: 2 },
|
||||||
|
componentProps: {
|
||||||
|
placeholder: '请输入内容',
|
||||||
|
min: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export function genFormSchemas({
|
||||||
|
label = '备注信息',
|
||||||
|
required = true,
|
||||||
|
inputType = 'InputTextArea',
|
||||||
|
defaultValue = '',
|
||||||
|
}: genFormSchemasProps) {
|
||||||
|
const formSchema: FormSchema = {
|
||||||
|
field: 'txt',
|
||||||
|
component: inputType,
|
||||||
|
label,
|
||||||
|
defaultValue,
|
||||||
|
required: Boolean(required),
|
||||||
|
...inputTypeMap[inputType],
|
||||||
|
};
|
||||||
|
return [formSchema];
|
||||||
|
}
|
||||||
|
|
@ -25,6 +25,12 @@
|
||||||
<a-button type="primary" class="my-4" @click="openTargetModal(4)"> 打开弹窗4 </a-button>
|
<a-button type="primary" class="my-4" @click="openTargetModal(4)"> 打开弹窗4 </a-button>
|
||||||
</a-space>
|
</a-space>
|
||||||
|
|
||||||
|
<Alert
|
||||||
|
message="使用函数方式创建Prompt,适合较为简单的表单内容,如果需要弹出较为复杂的内容,请使用 Modal."
|
||||||
|
show-icon
|
||||||
|
/>
|
||||||
|
<a-button type="primary" class="my-4" @click="handleCreatePrompt"> Prompt </a-button>
|
||||||
|
|
||||||
<component :is="currentModal" v-model:visible="modalVisible" :userData="userData" />
|
<component :is="currentModal" v-model:visible="modalVisible" :userData="userData" />
|
||||||
|
|
||||||
<Modal1 @register="register1" :minHeight="100" />
|
<Modal1 @register="register1" :minHeight="100" />
|
||||||
|
|
@ -35,7 +41,7 @@
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, shallowRef, ComponentOptions, ref, nextTick } from 'vue';
|
import { defineComponent, shallowRef, ComponentOptions, ref, nextTick } from 'vue';
|
||||||
import { Alert, Space } from 'ant-design-vue';
|
import { Alert, Space, message } from 'ant-design-vue';
|
||||||
import { useModal } from '/@/components/Modal';
|
import { useModal } from '/@/components/Modal';
|
||||||
import Modal1 from './Modal1.vue';
|
import Modal1 from './Modal1.vue';
|
||||||
import Modal2 from './Modal2.vue';
|
import Modal2 from './Modal2.vue';
|
||||||
|
|
@ -43,6 +49,7 @@
|
||||||
import Modal4 from './Modal4.vue';
|
import Modal4 from './Modal4.vue';
|
||||||
import { PageWrapper } from '/@/components/Page';
|
import { PageWrapper } from '/@/components/Page';
|
||||||
import { type Nullable } from '@vben/types';
|
import { type Nullable } from '@vben/types';
|
||||||
|
import { createPrompt } from '/@/components/Prompt';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { Alert, Modal1, Modal2, Modal3, Modal4, PageWrapper, ASpace: Space },
|
components: { Alert, Modal1, Modal2, Modal3, Modal4, PageWrapper, ASpace: Space },
|
||||||
|
|
@ -93,6 +100,19 @@
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleCreatePrompt() {
|
||||||
|
createPrompt({
|
||||||
|
title: '请输入邮箱',
|
||||||
|
required: true,
|
||||||
|
label: '邮箱',
|
||||||
|
defaultValue: '默认邮箱',
|
||||||
|
onOK: async (email: string) => {
|
||||||
|
message.success('填写的邮箱地址为' + email);
|
||||||
|
},
|
||||||
|
inputType: 'Input',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
register1,
|
register1,
|
||||||
openModal1,
|
openModal1,
|
||||||
|
|
@ -108,6 +128,7 @@
|
||||||
send,
|
send,
|
||||||
currentModal,
|
currentModal,
|
||||||
openModalLoading,
|
openModalLoading,
|
||||||
|
handleCreatePrompt,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue