mirror of
https://github.com/jeecgboot/JeecgBoot.git
synced 2026-02-05 18:15:28 +08:00
前端和后端源码,合并到一个git仓库中,方便用户下载,避免前后端不匹配的问题
This commit is contained in:
160
jeecgboot-vue3/src/components/jeecg/JPrompt/JPrompt.vue
Normal file
160
jeecgboot-vue3/src/components/jeecg/JPrompt/JPrompt.vue
Normal file
@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<ConfigProvider :locale="getAntdLocale">
|
||||
<Modal v-bind="getProps">
|
||||
<Spin :spinning="loading">
|
||||
<div style="padding: 20px;">
|
||||
<div v-html="options.content" style="margin-bottom: 8px"></div>
|
||||
<BasicForm @register="registerForm">
|
||||
<template #customInput="{ model, field }">
|
||||
<Input ref="inputRef" v-model:value="model[field]" :placeholder="placeholder" @pressEnter="onSubmit" @input="onChange" />
|
||||
</template>
|
||||
</BasicForm>
|
||||
</div>
|
||||
</Spin>
|
||||
</Modal>
|
||||
</ConfigProvider>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import type { JPromptProps } from './typing';
|
||||
import type { ModalProps } from '/@/components/Modal';
|
||||
import { ref, defineComponent, computed, unref, onMounted, nextTick } from 'vue';
|
||||
import { BasicForm, useForm } from '/@/components/Form';
|
||||
import { Modal, Spin, Input, ConfigProvider } from 'ant-design-vue';
|
||||
import { useLocale } from '/@/locales/useLocale';
|
||||
|
||||
export default defineComponent({
|
||||
name: 'JPrompt',
|
||||
components: {
|
||||
Modal,
|
||||
Spin,
|
||||
Input,
|
||||
BasicForm,
|
||||
ConfigProvider,
|
||||
},
|
||||
emits: ['register'],
|
||||
setup(props, { emit }) {
|
||||
const inputRef = ref();
|
||||
const { getAntdLocale } = useLocale();
|
||||
const visible = ref(false);
|
||||
// 当前是否正在加载中
|
||||
const loading = ref(false);
|
||||
const options = ref<JPromptProps>({});
|
||||
const placeholder = computed(() => options.value.placeholder ?? '请输入内容');
|
||||
// 注册表单
|
||||
const [registerForm, { clearValidate, setFieldsValue, validate, updateSchema }] = useForm({
|
||||
compact: true,
|
||||
wrapperCol: { span: 24 },
|
||||
schemas: [
|
||||
{
|
||||
label: '',
|
||||
field: 'input',
|
||||
component: 'Input',
|
||||
slot: 'customInput',
|
||||
},
|
||||
],
|
||||
showActionButtonGroup: false,
|
||||
});
|
||||
|
||||
// 弹窗最终props
|
||||
const getProps = computed(() => {
|
||||
let opt = options.value;
|
||||
let modalProps: Partial<ModalProps> = {
|
||||
width: (opt.width ?? 500) as number,
|
||||
title: (opt.title ?? 'prompt') as string,
|
||||
open: unref(visible),
|
||||
confirmLoading: unref(loading),
|
||||
};
|
||||
let finalProps: Recordable = {
|
||||
...modalProps,
|
||||
...props,
|
||||
...opt,
|
||||
onOk: onSubmit,
|
||||
onCancel() {
|
||||
if (typeof options.value.onCancel === 'function') {
|
||||
options.value.onCancel();
|
||||
}
|
||||
close();
|
||||
},
|
||||
};
|
||||
return finalProps;
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
emit('register', {
|
||||
openModal,
|
||||
setLoading,
|
||||
getVisible: visible,
|
||||
});
|
||||
});
|
||||
|
||||
/** 弹窗开启 */
|
||||
async function openModal(opt: any) {
|
||||
document.body.focus();
|
||||
|
||||
options.value = opt;
|
||||
visible.value = true;
|
||||
await nextTick();
|
||||
await updateSchema({
|
||||
field: 'input',
|
||||
required: options.value.required,
|
||||
rules: options.value.rules,
|
||||
dynamicRules: options.value.dynamicRules,
|
||||
} as any);
|
||||
await setFieldsValue({
|
||||
input: options.value.defaultValue ?? '',
|
||||
});
|
||||
await clearValidate();
|
||||
inputRef.value?.focus();
|
||||
}
|
||||
|
||||
/** 弹窗关闭 */
|
||||
function close() {
|
||||
visible.value = false;
|
||||
}
|
||||
|
||||
function onChange() {
|
||||
validate()
|
||||
}
|
||||
|
||||
/** 提交表单 */
|
||||
async function onSubmit() {
|
||||
try {
|
||||
const { onOk } = options.value;
|
||||
// 表单验证
|
||||
let values = await validate();
|
||||
setLoading(true);
|
||||
if (typeof onOk === 'function') {
|
||||
let flag = await onOk(values.input);
|
||||
// 只有返回 false 才阻止关闭弹窗
|
||||
if (!(flag === false)) {
|
||||
close();
|
||||
}
|
||||
} else {
|
||||
close();
|
||||
}
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
/** 设置加载状态*/
|
||||
function setLoading(flag) {
|
||||
loading.value = flag;
|
||||
}
|
||||
|
||||
return {
|
||||
inputRef,
|
||||
getProps,
|
||||
loading,
|
||||
options,
|
||||
placeholder,
|
||||
getAntdLocale,
|
||||
onChange,
|
||||
onSubmit,
|
||||
|
||||
registerForm,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@ -0,0 +1,57 @@
|
||||
import type { JPromptProps } from '../typing';
|
||||
import { render, createVNode, nextTick } from 'vue';
|
||||
import { error } from '/@/utils/log';
|
||||
import JPrompt from '../JPrompt.vue';
|
||||
|
||||
export function useJPrompt() {
|
||||
|
||||
function createJPrompt(options: JPromptProps) {
|
||||
let instance = null;
|
||||
const box = document.createElement('div');
|
||||
const vm = createVNode(JPrompt, {
|
||||
// 注册
|
||||
async onRegister(ins) {
|
||||
instance = ins;
|
||||
await nextTick();
|
||||
ins.openModal(options);
|
||||
},
|
||||
// 销毁
|
||||
afterClose() {
|
||||
render(null, box);
|
||||
document.body.removeChild(box);
|
||||
},
|
||||
});
|
||||
// 挂载到 body
|
||||
render(vm, box);
|
||||
document.body.appendChild(box);
|
||||
|
||||
function getInstance(): any {
|
||||
if (instance == null) {
|
||||
error('useJPrompt instance is undefined!');
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
function updateModal(options: JPromptProps) {
|
||||
getInstance()?.updateModal(options);
|
||||
}
|
||||
|
||||
function closeModal() {
|
||||
getInstance()?.closeModal();
|
||||
}
|
||||
|
||||
function setLoading(loading) {
|
||||
getInstance()?.setLoading(loading);
|
||||
}
|
||||
|
||||
return {
|
||||
closeModal,
|
||||
updateModal,
|
||||
setLoading,
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
createJPrompt,
|
||||
};
|
||||
}
|
||||
2
jeecgboot-vue3/src/components/jeecg/JPrompt/index.ts
Normal file
2
jeecgboot-vue3/src/components/jeecg/JPrompt/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export { useJPrompt } from './hooks/useJPrompt';
|
||||
export { default as JPrompt } from './JPrompt.vue';
|
||||
15
jeecgboot-vue3/src/components/jeecg/JPrompt/typing.ts
Normal file
15
jeecgboot-vue3/src/components/jeecg/JPrompt/typing.ts
Normal file
@ -0,0 +1,15 @@
|
||||
import { ModalOptionsPartial } from '/@/hooks/web/useMessage';
|
||||
import { RenderCallbackParams, Rule } from '/@/components/Form';
|
||||
|
||||
export interface JPromptProps extends ModalOptionsPartial {
|
||||
// 输入框是否必填
|
||||
required?: boolean;
|
||||
// 校验
|
||||
rules?: Rule[];
|
||||
// 动态校验
|
||||
dynamicRules?: (renderCallbackParams: RenderCallbackParams) => Rule[];
|
||||
// 占位字符
|
||||
placeholder?: string;
|
||||
// 输入框默认值
|
||||
defaultValue?: string;
|
||||
}
|
||||
Reference in New Issue
Block a user