This commit is contained in:
孟帅
2022-11-24 23:37:34 +08:00
parent 4ffe54b6ac
commit 29bda0dcdd
1487 changed files with 97869 additions and 96539 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,117 @@
<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" setup>
import {
getCurrentInstance,
ref,
nextTick,
unref,
computed,
useAttrs,
defineEmits,
defineProps,
} from 'vue';
import { basicProps } from './props';
import startDrag from '@/utils/Drag';
import { deepMerge } from '@/utils';
import { FormProps } from '@/components/Form';
import { ModalProps, ModalMethods } from './type';
const attrs = useAttrs();
const props = defineProps({ ...basicProps });
const emit = defineEmits(['on-close', 'on-ok', 'register']);
const propsRef = ref<Partial<ModalProps> | null>(null);
const isModal = ref(false);
const subLoading = ref(false);
const getProps = computed((): FormProps => {
return { ...props, ...(unref(propsRef) as any) };
});
const subBtuText = computed(() => {
const { subBtuText } = propsRef.value as any;
return subBtuText || props.subBtuText;
});
async function setProps(modalProps: Partial<ModalProps>): Promise<void> {
propsRef.value = deepMerge(unref(propsRef) || ({} as any), modalProps);
}
const getBindValue = computed(() => {
return {
...attrs,
...unref(getProps),
...unref(propsRef),
};
});
function setSubLoading(status: boolean) {
subLoading.value = status;
}
function openModal() {
isModal.value = true;
nextTick(() => {
const oBox = document.getElementById('basic-modal');
const oBar = document.getElementById('basic-modal-bar');
startDrag(oBar, oBox);
});
}
function closeModal() {
isModal.value = false;
subLoading.value = false;
emit('on-close');
}
function onCloseModal() {
isModal.value = false;
emit('on-close');
}
function handleSubmit() {
subLoading.value = true;
console.log(subLoading.value);
emit('on-ok');
}
const modalMethods: ModalMethods = {
setProps,
openModal,
closeModal,
setSubLoading,
};
const instance = getCurrentInstance();
if (instance) {
emit('register', modalMethods);
}
</script>
<style lang="less">
.cursor-move {
cursor: move;
}
</style>

View File

@@ -0,0 +1,54 @@
import { ref, unref, getCurrentInstance, watch } from 'vue';
import { isProdMode } from '@/utils/env';
import { ModalMethods, UseModalReturnType } from '../type';
import { getDynamicProps } from '@/utils';
import { tryOnUnmounted } from '@vueuse/core';
export function useModal(props): UseModalReturnType {
const modalRef = ref<Nullable<ModalMethods>>(null);
const currentInstance = getCurrentInstance();
const getInstance = () => {
const instance = unref(modalRef.value);
if (!instance) {
console.error('useModal instance is undefined!');
}
return instance;
};
const register = (modalInstance: ModalMethods) => {
isProdMode() &&
tryOnUnmounted(() => {
modalRef.value = null;
});
modalRef.value = modalInstance;
currentInstance?.emit('register', modalInstance);
watch(
() => props,
() => {
props && modalInstance.setProps(getDynamicProps(props));
},
{
immediate: true,
deep: true,
}
);
};
const methods: ModalMethods = {
setProps: (props): void => {
getInstance()?.setProps(props);
},
openModal: () => {
getInstance()?.openModal();
},
closeModal: () => {
getInstance()?.closeModal();
},
setSubLoading: (status) => {
getInstance()?.setSubLoading(status);
},
};
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,19 @@
import type { DialogOptions } from 'naive-ui/lib/dialog';
/**
* @description: 弹窗对外暴露的方法
*/
export interface ModalMethods {
setProps: (props) => void;
openModal: () => void;
closeModal: () => void;
setSubLoading: (status) => void;
}
/**
* 支持修改DialogOptions 參數
*/
export type ModalProps = DialogOptions;
export type RegisterFn = (ModalInstance: ModalMethods) => void;
export type UseModalReturnType = [RegisterFn, ModalMethods];