支持 Vue 3.2.x 语法升级为,script setup

This commit is contained in:
xiaoma
2021-08-14 14:35:42 +08:00
parent d3f7fa0f9e
commit 905984367c
71 changed files with 2362 additions and 2116 deletions

View File

@@ -20,104 +20,88 @@
</n-modal>
</template>
<script lang="ts">
<script lang="ts" setup>
import {
defineComponent,
getCurrentInstance,
ref,
nextTick,
unref,
toRefs,
reactive,
computed,
useAttrs,
defineEmits,
defineProps,
} 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>({});
import { ModalProps, ModalMethods } from './type';
const state = reactive({
isModal: false,
subLoading: false,
});
const attrs = useAttrs();
const props = defineProps({ ...basicProps });
const emit = defineEmits(['on-close', 'on-ok', 'register']);
const getProps = computed((): FormProps => {
const modalProps = { ...props, ...unref(propsRef) };
return { ...modalProps };
});
const propsRef = ref(<Partial<ModalProps> | null>null);
async function setProps(modalProps: Partial): Promise<void> {
propsRef.value = deepMerge(unref(propsRef) || {}, modalProps);
}
const isModal = ref(false);
const subLoading = ref(false);
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,
};
},
const getProps = computed((): FormProps => {
return { ...props, ...(unref(propsRef) as any) };
});
async function setProps(modalProps: Partial<ModalProps>): Promise<void> {
propsRef.value = deepMerge(unref(propsRef) || ({} as any), modalProps);
}
const getBindValue = computed(() => {
return {
...attrs,
...unref(getProps),
};
});
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;
emit('on-ok');
}
const modalMethods: ModalMethods = {
setProps,
openModal,
closeModal,
setSubLoading,
};
const instance = getCurrentInstance();
if (instance) {
emit('register', modalMethods);
}
</script>
<style lang="less">

View File

@@ -1,46 +1,42 @@
import { ref, onUnmounted, unref, getCurrentInstance, watch } from 'vue';
import { ref, onUnmounted, unref, getCurrentInstance, watch, nextTick } from 'vue';
import { isProdMode } from '@/utils/env';
import { ReturnMethods } from '../type';
import { ModalMethods, UseModalReturnType } from '../type';
import { getDynamicProps } from '@/utils';
export function useModal(props): (((modalMethod: ReturnMethods) => any) | ReturnMethods)[] {
const modal = ref<Nullable<ReturnMethods>>(null);
const loaded = ref<Nullable<boolean>>(false);
import { tryOnUnmounted } from '@vueuse/core';
export function useModal(props): UseModalReturnType {
function register(modalMethod: ReturnMethods) {
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,
() => {
// @ts-ignore
const { setProps } = modal.value;
props && setProps(getDynamicProps(props));
},
{
immediate: true,
deep: true,
}
);
}
const modalRef = ref<Nullable<ModalMethods>>(null);
const currentInstance = getCurrentInstance();
const getInstance = () => {
const instance = unref(modal);
const instance = unref(modalRef.value);
if (!instance) {
console.error('useModal instance is undefined!');
}
return instance;
};
const methods: ReturnMethods = {
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);
},
@@ -54,5 +50,6 @@ export function useModal(props): (((modalMethod: ReturnMethods) => any) | Return
getInstance()?.setSubLoading(status);
},
};
return [register, methods];
}

View File

@@ -1,9 +1,19 @@
import type { DialogOptions } from 'naive-ui/lib/dialog';
/**
* @description: 弹窗对外暴露的方法
*/
export interface ReturnMethods {
export interface ModalMethods {
setProps: (props) => void;
openModal: () => void;
closeModal: () => void;
setSubLoading: (status) => void;
}
/**
* 支持修改DialogOptions 參數
*/
export interface ModalProps extends DialogOptions { }
export type RegisterFn = (ModalInstance: ModalMethods) => void;
export type UseModalReturnType = [RegisterFn, ModalMethods];