Fixes bug add baseModal | baseForm 组件

This commit is contained in:
Ah jung
2021-08-05 17:24:24 +08:00
parent 98e1bf0227
commit 8a5f237630
59 changed files with 2056 additions and 106 deletions

View File

@@ -0,0 +1,3 @@
export { default as basicModal } from './src/basicModal.vue';
export { useModal } from './src/hooks/useModal';
export * from './src/type';

View File

@@ -0,0 +1,127 @@
<template>
<n-modal id="basic-modal" v-bind="getBindValue" v-model:show="isModal" @close="onCloseModal">
<template #header>
<div class="w-full cursor-move" id="basic-modal-bar">{{ getBindValue.title }}</div>
</template>
<template #default>
<slot name="default"></slot>
</template>
<template #action v-if="!$slots.action">
<n-space>
<n-button @click="closeModal">取消</n-button>
<n-button type="primary" :loading="subLoading" @click="handleSubmit">{{
subBtuText
}}</n-button>
</n-space>
</template>
<template v-else #action>
<slot name="action"></slot>
</template>
</n-modal>
</template>
<script lang="ts">
import {
defineComponent,
getCurrentInstance,
ref,
nextTick,
unref,
toRefs,
reactive,
computed,
} from 'vue';
import { basicProps } from './props';
import startDrag from '@/utils/Drag';
import { deepMerge } from '@/utils';
import { FormProps } from '@/components/Form';
export default defineComponent({
name: 'BasicModal',
components: {},
props: {
...basicProps,
},
emits: ['on-close', 'on-ok', 'register'],
setup(props, { emit, attrs }) {
const propsRef = ref<Partial>({});
const state = reactive({
isModal: false,
subLoading: false,
});
const getProps = computed((): FormProps => {
const modalProps = { ...props, ...unref(propsRef) };
return { ...modalProps };
});
async function setProps(modalProps: Partial): Promise<void> {
propsRef.value = deepMerge(unref(propsRef) || {}, modalProps);
}
const getBindValue = computed(() => {
return {
...attrs,
...unref(getProps),
};
});
function setSubLoading(status: boolean) {
state.subLoading = status;
}
function openModal() {
state.isModal = true;
nextTick(() => {
const oBox = document.getElementById('basic-modal');
const oBar = document.getElementById('basic-modal-bar');
startDrag(oBar, oBox);
});
}
function closeModal() {
state.isModal = false;
state.subLoading = false;
emit('on-close');
}
function onCloseModal() {
state.isModal = false;
emit('on-close');
}
function handleSubmit() {
state.subLoading = true;
emit('on-ok');
}
const modalMethods: ModalMethods = {
setProps,
openModal,
closeModal,
setSubLoading,
};
const instance = getCurrentInstance();
if (instance) {
emit('register', modalMethods);
}
return {
...toRefs(state),
getBindValue,
openModal,
closeModal,
onCloseModal,
handleSubmit,
setProps,
};
},
});
</script>
<style lang="less">
.cursor-move {
cursor: move;
}
</style>

View File

@@ -0,0 +1,57 @@
import { ref, onUnmounted, unref, getCurrentInstance, watch } from 'vue';
import { isProdMode } from '@/utils/env';
import { UseModalReturnType, ModalMethods } from './type';
import { getDynamicProps } from '@/utils';
export function useModal(props?: Props): UseModalReturnType {
const modal = ref<Nullable<ModalMethods>>(null);
const loaded = ref<Nullable<boolean>>(false);
function register(modalMethod: ModalMethods) {
if (!getCurrentInstance()) {
throw new Error('useModal() can only be used inside setup() or functional components!');
}
isProdMode() &&
onUnmounted(() => {
modal.value = null;
loaded.value = false;
});
if (unref(loaded) && isProdMode() && modalMethod === unref(modal)) return;
modal.value = modalMethod;
watch(
() => props,
() => {
const { setProps } = modal.value;
props && setProps(getDynamicProps(props));
},
{
immediate: true,
deep: true,
}
);
}
const getInstance = () => {
const instance = unref(modal);
if (!instance) {
error('useModal instance is undefined!');
}
return instance;
};
const methods: ReturnMethods = {
setProps: (props: Partial<ModalProps>): void => {
getInstance()?.setProps(props);
},
openModal: () => {
getInstance()?.openModal();
},
closeModal: () => {
getInstance()?.closeModal();
},
setSubLoading: () => {
getInstance()?.setSubLoading();
},
};
return [register, methods];
}

View File

@@ -0,0 +1,30 @@
import { NModal } from 'naive-ui';
export const basicProps = {
...NModal.props,
// 确认按钮文字
subBtuText: {
type: String,
default: '确认',
},
showIcon: {
type: Boolean,
default: false,
},
width: {
type: Number,
default: 446,
},
title: {
type: String,
default: '',
},
maskClosable: {
type: Boolean,
default: false,
},
preset: {
type: String,
default: 'dialog',
},
};

View File

@@ -0,0 +1,12 @@
export interface ModalProps {
subBtuText?: string;
}
/**
* @description: 弹窗对外暴露的方法
*/
export interface ModalMethods {
setProps: (props: Partial<ModalProps>) => void;
openModal: () => void;
closeModal: () => void;
}