mirror of
https://github.com/vbenjs/gf-vben-admin.git
synced 2025-01-23 20:00:19 +08:00
fix(modal): ensure that the full screen height is calculated correctly
This commit is contained in:
parent
639520ad5d
commit
1c1755cf5b
@ -2,9 +2,15 @@
|
|||||||
|
|
||||||
### ✨ Features
|
### ✨ Features
|
||||||
|
|
||||||
- `Cropper` 头像裁剪新增圆形裁剪功能
|
- **CropperImage** `Cropper` 头像裁剪新增圆形裁剪功能
|
||||||
- 新增头像上传组件
|
- **CropperAvatar** 新增头像上传组件
|
||||||
- `useDrawer`新增`closeDrawer`函数
|
- **Drawer** `useDrawer`新增`closeDrawer`函数
|
||||||
|
|
||||||
|
### 🐛 Bug Fixes
|
||||||
|
|
||||||
|
- **Modal** 修复全屏高度计算错误
|
||||||
|
- **PageWrapper** 修复高度计算问题
|
||||||
|
- 修复后台模式下,Iframe 路由错误
|
||||||
|
|
||||||
## 2.4.2(2021-06-10)
|
## 2.4.2(2021-06-10)
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@
|
|||||||
|
|
||||||
function setDrawerProps(props: Partial<DrawerProps>): void {
|
function setDrawerProps(props: Partial<DrawerProps>): void {
|
||||||
// Keep the last setDrawerProps
|
// Keep the last setDrawerProps
|
||||||
propsRef.value = deepMerge((unref(propsRef) as any) || {}, props);
|
propsRef.value = deepMerge(unref(propsRef), props);
|
||||||
|
|
||||||
if (Reflect.has(props, 'visible')) {
|
if (Reflect.has(props, 'visible')) {
|
||||||
visibleRef.value = !!props.visible;
|
visibleRef.value = !!props.visible;
|
||||||
|
@ -5,7 +5,6 @@ import type {
|
|||||||
DrawerProps,
|
DrawerProps,
|
||||||
UseDrawerInnerReturnType,
|
UseDrawerInnerReturnType,
|
||||||
} from './typing';
|
} from './typing';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ref,
|
ref,
|
||||||
getCurrentInstance,
|
getCurrentInstance,
|
||||||
@ -16,11 +15,9 @@ import {
|
|||||||
toRaw,
|
toRaw,
|
||||||
computed,
|
computed,
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
|
|
||||||
import { isProdMode } from '/@/utils/env';
|
import { isProdMode } from '/@/utils/env';
|
||||||
import { isFunction } from '/@/utils/is';
|
import { isFunction } from '/@/utils/is';
|
||||||
import { tryOnUnmounted } from '@vueuse/core';
|
import { tryOnUnmounted } from '@vueuse/core';
|
||||||
|
|
||||||
import { isEqual } from 'lodash-es';
|
import { isEqual } from 'lodash-es';
|
||||||
import { error } from '/@/utils/log';
|
import { error } from '/@/utils/log';
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
|
import { withInstall } from '/@/utils';
|
||||||
import './src/index.less';
|
import './src/index.less';
|
||||||
import BasicModal from './src/BasicModal.vue';
|
import basicModal from './src/BasicModal.vue';
|
||||||
|
|
||||||
export { BasicModal };
|
export const BasicModal = withInstall(basicModal);
|
||||||
export { useModalContext } from './src/hooks/useModalContext';
|
export { useModalContext } from './src/hooks/useModalContext';
|
||||||
export { useModal, useModalInner } from './src/hooks/useModal';
|
export { useModal, useModalInner } from './src/hooks/useModal';
|
||||||
export * from './src/types';
|
export * from './src/typing';
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { ModalProps, ModalMethods } from './types';
|
import type { ModalProps, ModalMethods } from './typing';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
defineComponent,
|
defineComponent,
|
||||||
@ -62,20 +62,17 @@
|
|||||||
getCurrentInstance,
|
getCurrentInstance,
|
||||||
nextTick,
|
nextTick,
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
|
|
||||||
import Modal from './components/Modal';
|
import Modal from './components/Modal';
|
||||||
import ModalWrapper from './components/ModalWrapper.vue';
|
import ModalWrapper from './components/ModalWrapper.vue';
|
||||||
import ModalClose from './components/ModalClose.vue';
|
import ModalClose from './components/ModalClose.vue';
|
||||||
import ModalFooter from './components/ModalFooter.vue';
|
import ModalFooter from './components/ModalFooter.vue';
|
||||||
import ModalHeader from './components/ModalHeader.vue';
|
import ModalHeader from './components/ModalHeader.vue';
|
||||||
|
|
||||||
import { isFunction } from '/@/utils/is';
|
import { isFunction } from '/@/utils/is';
|
||||||
import { deepMerge } from '/@/utils';
|
import { deepMerge } from '/@/utils';
|
||||||
|
|
||||||
import { basicProps } from './props';
|
import { basicProps } from './props';
|
||||||
import { useFullScreen } from './hooks/useModalFullScreen';
|
import { useFullScreen } from './hooks/useModalFullScreen';
|
||||||
|
|
||||||
import { omit } from 'lodash-es';
|
import { omit } from 'lodash-es';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'BasicModal',
|
name: 'BasicModal',
|
||||||
components: { Modal, ModalWrapper, ModalClose, ModalFooter, ModalHeader },
|
components: { Modal, ModalWrapper, ModalClose, ModalFooter, ModalHeader },
|
||||||
@ -189,7 +186,7 @@
|
|||||||
*/
|
*/
|
||||||
function setModalProps(props: Partial<ModalProps>): void {
|
function setModalProps(props: Partial<ModalProps>): void {
|
||||||
// Keep the last setModalProps
|
// Keep the last setModalProps
|
||||||
propsRef.value = deepMerge(unref(propsRef) || {}, props);
|
propsRef.value = deepMerge(unref(propsRef), props);
|
||||||
if (!Reflect.has(props, 'visible')) return;
|
if (!Reflect.has(props, 'visible')) return;
|
||||||
visibleRef.value = !!props.visible;
|
visibleRef.value = !!props.visible;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,6 @@ export default defineComponent({
|
|||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
const propsData = { ...unref(attrs), ...props } as Recordable;
|
const propsData = { ...unref(attrs), ...props } as Recordable;
|
||||||
|
|
||||||
return <Modal {...propsData}>{extendSlots(slots)}</Modal>;
|
return <Modal {...propsData}>{extendSlots(slots)}</Modal>;
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
<div :class="getClass">
|
<div :class="getClass">
|
||||||
<template v-if="canFullscreen">
|
<template v-if="canFullscreen">
|
||||||
<FullscreenExitOutlined role="full" @click="handleFullScreen" v-if="fullScreen" />
|
<FullscreenExitOutlined role="full" @click="handleFullScreen" v-if="fullScreen" />
|
||||||
|
|
||||||
<FullscreenOutlined role="close" @click="handleFullScreen" v-else />
|
<FullscreenOutlined role="close" @click="handleFullScreen" v-else />
|
||||||
</template>
|
</template>
|
||||||
<CloseOutlined @click="handleCancel" />
|
<CloseOutlined @click="handleCancel" />
|
||||||
@ -12,14 +11,13 @@
|
|||||||
import { defineComponent, computed } from 'vue';
|
import { defineComponent, computed } from 'vue';
|
||||||
import { FullscreenExitOutlined, FullscreenOutlined, CloseOutlined } from '@ant-design/icons-vue';
|
import { FullscreenExitOutlined, FullscreenOutlined, CloseOutlined } from '@ant-design/icons-vue';
|
||||||
import { useDesign } from '/@/hooks/web/useDesign';
|
import { useDesign } from '/@/hooks/web/useDesign';
|
||||||
import { propTypes } from '/@/utils/propTypes';
|
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'ModalClose',
|
name: 'ModalClose',
|
||||||
components: { FullscreenExitOutlined, FullscreenOutlined, CloseOutlined },
|
components: { FullscreenExitOutlined, FullscreenOutlined, CloseOutlined },
|
||||||
props: {
|
props: {
|
||||||
canFullscreen: propTypes.bool.def(true),
|
canFullscreen: { type: Boolean, default: true },
|
||||||
fullScreen: propTypes.bool,
|
fullScreen: { type: Boolean },
|
||||||
},
|
},
|
||||||
emits: ['cancel', 'fullscreen'],
|
emits: ['cancel', 'fullscreen'],
|
||||||
setup(props, { emit }) {
|
setup(props, { emit }) {
|
||||||
@ -38,6 +36,7 @@
|
|||||||
function handleCancel(e: Event) {
|
function handleCancel(e: Event) {
|
||||||
emit('cancel', e);
|
emit('cancel', e);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleFullScreen(e: Event) {
|
function handleFullScreen(e: Event) {
|
||||||
e?.stopPropagation();
|
e?.stopPropagation();
|
||||||
e?.preventDefault();
|
e?.preventDefault();
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
function handleCancel(e: Event) {
|
function handleCancel(e: Event) {
|
||||||
emit('cancel', e);
|
emit('cancel', e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return { handleOk, handleCancel };
|
return { handleOk, handleCancel };
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -8,7 +8,6 @@
|
|||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { BasicTitle } from '/@/components/Basic';
|
import { BasicTitle } from '/@/components/Basic';
|
||||||
|
|
||||||
import { propTypes } from '/@/utils/propTypes';
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'BasicModalHeader',
|
name: 'BasicModalHeader',
|
||||||
components: { BasicTitle },
|
components: { BasicTitle },
|
||||||
@ -16,7 +15,7 @@
|
|||||||
helpMessage: {
|
helpMessage: {
|
||||||
type: [String, Array] as PropType<string | string[]>,
|
type: [String, Array] as PropType<string | string[]>,
|
||||||
},
|
},
|
||||||
title: propTypes.string,
|
title: { type: String },
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -6,9 +6,7 @@
|
|||||||
</ScrollContainer>
|
</ScrollContainer>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import type { ModalWrapperProps } from '../types';
|
|
||||||
import type { CSSProperties } from 'vue';
|
import type { CSSProperties } from 'vue';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
defineComponent,
|
defineComponent,
|
||||||
computed,
|
computed,
|
||||||
@ -20,31 +18,31 @@
|
|||||||
nextTick,
|
nextTick,
|
||||||
onUnmounted,
|
onUnmounted,
|
||||||
} from 'vue';
|
} from 'vue';
|
||||||
|
|
||||||
import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
|
import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
|
||||||
import { ScrollContainer } from '/@/components/Container';
|
import { ScrollContainer } from '/@/components/Container';
|
||||||
|
|
||||||
import { propTypes } from '/@/utils/propTypes';
|
|
||||||
import { createModalContext } from '../hooks/useModalContext';
|
import { createModalContext } from '../hooks/useModalContext';
|
||||||
|
import { useMutationObserver } from '@vueuse/core';
|
||||||
|
|
||||||
|
const props = {
|
||||||
|
loading: { type: Boolean },
|
||||||
|
useWrapper: { type: Boolean, default: true },
|
||||||
|
modalHeaderHeight: { type: Number, default: 57 },
|
||||||
|
modalFooterHeight: { type: Number, default: 74 },
|
||||||
|
minHeight: { type: Number, default: 200 },
|
||||||
|
height: { type: Number },
|
||||||
|
footerOffset: { type: Number, default: 0 },
|
||||||
|
visible: { type: Boolean },
|
||||||
|
fullScreen: { type: Boolean },
|
||||||
|
loadingTip: { type: String },
|
||||||
|
};
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'ModalWrapper',
|
name: 'ModalWrapper',
|
||||||
components: { ScrollContainer },
|
components: { ScrollContainer },
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: {
|
props,
|
||||||
loading: propTypes.bool,
|
|
||||||
useWrapper: propTypes.bool.def(true),
|
|
||||||
modalHeaderHeight: propTypes.number.def(57),
|
|
||||||
modalFooterHeight: propTypes.number.def(74),
|
|
||||||
minHeight: propTypes.number.def(200),
|
|
||||||
height: propTypes.number,
|
|
||||||
footerOffset: propTypes.number.def(0),
|
|
||||||
visible: propTypes.bool,
|
|
||||||
fullScreen: propTypes.bool,
|
|
||||||
loadingTip: propTypes.string,
|
|
||||||
},
|
|
||||||
emits: ['height-change', 'ext-height'],
|
emits: ['height-change', 'ext-height'],
|
||||||
setup(props: ModalWrapperProps, { emit }) {
|
setup(props, { emit }) {
|
||||||
const wrapperRef = ref<ComponentRef>(null);
|
const wrapperRef = ref<ComponentRef>(null);
|
||||||
const spinRef = ref<ElRef>(null);
|
const spinRef = ref<ElRef>(null);
|
||||||
const realHeightRef = ref(0);
|
const realHeightRef = ref(0);
|
||||||
@ -56,6 +54,17 @@
|
|||||||
|
|
||||||
useWindowSizeFn(setModalHeight.bind(null, false));
|
useWindowSizeFn(setModalHeight.bind(null, false));
|
||||||
|
|
||||||
|
useMutationObserver(
|
||||||
|
spinRef,
|
||||||
|
() => {
|
||||||
|
setModalHeight();
|
||||||
|
},
|
||||||
|
{
|
||||||
|
attributes: true,
|
||||||
|
subtree: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
createModalContext({
|
createModalContext({
|
||||||
redoModalHeight: setModalHeight,
|
redoModalHeight: setModalHeight,
|
||||||
});
|
});
|
||||||
@ -63,8 +72,7 @@
|
|||||||
const spinStyle = computed((): CSSProperties => {
|
const spinStyle = computed((): CSSProperties => {
|
||||||
return {
|
return {
|
||||||
minHeight: `${props.minHeight}px`,
|
minHeight: `${props.minHeight}px`,
|
||||||
// padding 28
|
[props.fullScreen ? 'height' : 'maxHeight']: `${unref(realHeightRef)}px`,
|
||||||
maxHeight: `${unref(realHeightRef)}px`,
|
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -87,7 +95,6 @@
|
|||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
const { modalHeaderHeight, modalFooterHeight } = props;
|
const { modalHeaderHeight, modalFooterHeight } = props;
|
||||||
emit('ext-height', modalHeaderHeight + modalFooterHeight);
|
emit('ext-height', modalHeaderHeight + modalFooterHeight);
|
||||||
// listenElResize();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
|
@ -4,8 +4,7 @@ import type {
|
|||||||
ModalProps,
|
ModalProps,
|
||||||
ReturnMethods,
|
ReturnMethods,
|
||||||
UseModalInnerReturnType,
|
UseModalInnerReturnType,
|
||||||
} from '../types';
|
} from '../typing';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ref,
|
ref,
|
||||||
onUnmounted,
|
onUnmounted,
|
||||||
@ -20,10 +19,10 @@ import { isProdMode } from '/@/utils/env';
|
|||||||
import { isFunction } from '/@/utils/is';
|
import { isFunction } from '/@/utils/is';
|
||||||
import { isEqual } from 'lodash-es';
|
import { isEqual } from 'lodash-es';
|
||||||
import { tryOnUnmounted } from '@vueuse/core';
|
import { tryOnUnmounted } from '@vueuse/core';
|
||||||
|
|
||||||
import { error } from '/@/utils/log';
|
import { error } from '/@/utils/log';
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
const dataTransferRef = reactive<any>({});
|
|
||||||
|
const dataTransfer = reactive<any>({});
|
||||||
|
|
||||||
const visibleData = reactive<{ [key: number]: boolean }>({});
|
const visibleData = reactive<{ [key: number]: boolean }>({});
|
||||||
|
|
||||||
@ -31,29 +30,31 @@ const visibleData = reactive<{ [key: number]: boolean }>({});
|
|||||||
* @description: Applicable to independent modal and call outside
|
* @description: Applicable to independent modal and call outside
|
||||||
*/
|
*/
|
||||||
export function useModal(): UseModalReturnType {
|
export function useModal(): UseModalReturnType {
|
||||||
const modalRef = ref<Nullable<ModalMethods>>(null);
|
const modal = ref<Nullable<ModalMethods>>(null);
|
||||||
const loadedRef = ref<Nullable<boolean>>(false);
|
const loaded = ref<Nullable<boolean>>(false);
|
||||||
const uidRef = ref<string>('');
|
const uid = ref<string>('');
|
||||||
|
|
||||||
function register(modalMethod: ModalMethods, uuid: string) {
|
function register(modalMethod: ModalMethods, uuid: string) {
|
||||||
uidRef.value = uuid;
|
if (!getCurrentInstance()) {
|
||||||
|
throw new Error('useModal() can only be used inside setup() or functional components!');
|
||||||
|
}
|
||||||
|
uid.value = uuid;
|
||||||
isProdMode() &&
|
isProdMode() &&
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
modalRef.value = null;
|
modal.value = null;
|
||||||
loadedRef.value = false;
|
loaded.value = false;
|
||||||
dataTransferRef[unref(uidRef)] = null;
|
dataTransfer[unref(uid)] = null;
|
||||||
});
|
});
|
||||||
if (unref(loadedRef) && isProdMode() && modalMethod === unref(modalRef)) return;
|
if (unref(loaded) && isProdMode() && modalMethod === unref(modal)) return;
|
||||||
|
|
||||||
modalRef.value = modalMethod;
|
modal.value = modalMethod;
|
||||||
modalMethod.emitVisible = (visible: boolean, uid: number) => {
|
modalMethod.emitVisible = (visible: boolean, uid: number) => {
|
||||||
visibleData[uid] = visible;
|
visibleData[uid] = visible;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const getInstance = () => {
|
const getInstance = () => {
|
||||||
const instance = unref(modalRef);
|
const instance = unref(modal);
|
||||||
if (!instance) {
|
if (!instance) {
|
||||||
error('useModal instance is undefined!');
|
error('useModal instance is undefined!');
|
||||||
}
|
}
|
||||||
@ -66,7 +67,7 @@ export function useModal(): UseModalReturnType {
|
|||||||
},
|
},
|
||||||
|
|
||||||
getVisible: computed((): boolean => {
|
getVisible: computed((): boolean => {
|
||||||
return visibleData[~~unref(uidRef)];
|
return visibleData[~~unref(uid)];
|
||||||
}),
|
}),
|
||||||
|
|
||||||
redoModalHeight: () => {
|
redoModalHeight: () => {
|
||||||
@ -79,15 +80,15 @@ export function useModal(): UseModalReturnType {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
|
const id = unref(uid);
|
||||||
if (openOnSet) {
|
if (openOnSet) {
|
||||||
dataTransferRef[unref(uidRef)] = null;
|
dataTransfer[id] = null;
|
||||||
dataTransferRef[unref(uidRef)] = toRaw(data);
|
dataTransfer[id] = toRaw(data);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const equal = isEqual(toRaw(dataTransferRef[unref(uidRef)]), toRaw(data));
|
const equal = isEqual(toRaw(dataTransfer[id]), toRaw(data));
|
||||||
if (!equal) {
|
if (!equal) {
|
||||||
dataTransferRef[unref(uidRef)] = toRaw(data);
|
dataTransfer[id] = toRaw(data);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -103,9 +104,6 @@ export const useModalInner = (callbackFn?: Fn): UseModalInnerReturnType => {
|
|||||||
const currentInstance = getCurrentInstance();
|
const currentInstance = getCurrentInstance();
|
||||||
const uidRef = ref<string>('');
|
const uidRef = ref<string>('');
|
||||||
|
|
||||||
// currentInstall.type.emits = [...currentInstall.type.emits, 'register'];
|
|
||||||
// Object.assign(currentInstall.type.emits, ['register']);
|
|
||||||
|
|
||||||
const getInstance = () => {
|
const getInstance = () => {
|
||||||
const instance = unref(modalInstanceRef);
|
const instance = unref(modalInstanceRef);
|
||||||
if (!instance) {
|
if (!instance) {
|
||||||
@ -125,7 +123,7 @@ export const useModalInner = (callbackFn?: Fn): UseModalInnerReturnType => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
watchEffect(() => {
|
watchEffect(() => {
|
||||||
const data = dataTransferRef[unref(uidRef)];
|
const data = dataTransfer[unref(uidRef)];
|
||||||
if (!data) return;
|
if (!data) return;
|
||||||
if (!callbackFn || !isFunction(callbackFn)) return;
|
if (!callbackFn || !isFunction(callbackFn)) return;
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
|
@ -12,7 +12,6 @@ export function useFullScreen(context: UseFullScreenContext) {
|
|||||||
|
|
||||||
const getWrapClassName = computed(() => {
|
const getWrapClassName = computed(() => {
|
||||||
const clsName = unref(context.wrapClassName) || '';
|
const clsName = unref(context.wrapClassName) || '';
|
||||||
|
|
||||||
return unref(fullScreenRef) ? `fullscreen-modal ${clsName} ` : unref(clsName);
|
return unref(fullScreenRef) ? `fullscreen-modal ${clsName} ` : unref(clsName);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,45 +1,44 @@
|
|||||||
import type { PropType, CSSProperties } from 'vue';
|
import type { PropType, CSSProperties } from 'vue';
|
||||||
|
import type { ModalWrapperProps } from './typing';
|
||||||
import { ButtonProps } from 'ant-design-vue/es/button/buttonTypes';
|
import { ButtonProps } from 'ant-design-vue/es/button/buttonTypes';
|
||||||
|
|
||||||
import { useI18n } from '/@/hooks/web/useI18n';
|
import { useI18n } from '/@/hooks/web/useI18n';
|
||||||
import { propTypes, VueNode } from '/@/utils/propTypes';
|
|
||||||
import type { ModalWrapperProps } from './types';
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
export const modalProps = {
|
export const modalProps = {
|
||||||
visible: propTypes.bool,
|
visible: { type: Boolean },
|
||||||
scrollTop: propTypes.bool.def(true),
|
scrollTop: { type: Boolean, default: true },
|
||||||
height: propTypes.number,
|
height: { type: Number },
|
||||||
minHeight: propTypes.number,
|
minHeight: { type: Number },
|
||||||
// open drag
|
// open drag
|
||||||
draggable: propTypes.bool.def(true),
|
draggable: { type: Boolean, default: true },
|
||||||
centered: propTypes.bool,
|
centered: { type: Boolean },
|
||||||
cancelText: propTypes.string.def(t('common.cancelText')),
|
cancelText: { type: String, default: t('common.cancelText') },
|
||||||
okText: propTypes.string.def(t('common.okText')),
|
okText: { type: String, default: t('common.okText') },
|
||||||
|
|
||||||
closeFunc: Function as PropType<() => Promise<boolean>>,
|
closeFunc: Function as PropType<() => Promise<boolean>>,
|
||||||
};
|
};
|
||||||
|
|
||||||
export const basicProps = Object.assign({}, modalProps, {
|
export const basicProps = Object.assign({}, modalProps, {
|
||||||
defaultFullscreen: propTypes.bool,
|
defaultFullscreen: { type: Boolean },
|
||||||
// Can it be full screen
|
// Can it be full screen
|
||||||
canFullscreen: propTypes.bool.def(true),
|
canFullscreen: { type: Boolean, default: true },
|
||||||
// After enabling the wrapper, the bottom can be increased in height
|
// After enabling the wrapper, the bottom can be increased in height
|
||||||
wrapperFooterOffset: propTypes.number.def(0),
|
wrapperFooterOffset: { type: Number, default: 0 },
|
||||||
// Warm reminder message
|
// Warm reminder message
|
||||||
helpMessage: [String, Array] as PropType<string | string[]>,
|
helpMessage: [String, Array] as PropType<string | string[]>,
|
||||||
// Whether to setting wrapper
|
// Whether to setting wrapper
|
||||||
useWrapper: propTypes.bool.def(true),
|
useWrapper: { type: Boolean, default: true },
|
||||||
loading: propTypes.bool,
|
loading: { type: Boolean },
|
||||||
loadingTip: propTypes.string,
|
loadingTip: { type: String },
|
||||||
/**
|
/**
|
||||||
* @description: Show close button
|
* @description: Show close button
|
||||||
*/
|
*/
|
||||||
showCancelBtn: propTypes.bool.def(true),
|
showCancelBtn: { type: Boolean, default: true },
|
||||||
/**
|
/**
|
||||||
* @description: Show confirmation button
|
* @description: Show confirmation button
|
||||||
*/
|
*/
|
||||||
showOkBtn: propTypes.bool.def(true),
|
showOkBtn: { type: Boolean, default: true },
|
||||||
|
|
||||||
wrapperProps: Object as PropType<Partial<ModalWrapperProps>>,
|
wrapperProps: Object as PropType<Partial<ModalWrapperProps>>,
|
||||||
|
|
||||||
@ -47,38 +46,38 @@ export const basicProps = Object.assign({}, modalProps, {
|
|||||||
|
|
||||||
bodyStyle: Object as PropType<CSSProperties>,
|
bodyStyle: Object as PropType<CSSProperties>,
|
||||||
|
|
||||||
closable: propTypes.bool.def(true),
|
closable: { type: Boolean, default: true },
|
||||||
|
|
||||||
closeIcon: Object as PropType<VueNode>,
|
closeIcon: Object as PropType<VueNode>,
|
||||||
|
|
||||||
confirmLoading: propTypes.bool,
|
confirmLoading: { type: Boolean },
|
||||||
|
|
||||||
destroyOnClose: propTypes.bool,
|
destroyOnClose: { type: Boolean },
|
||||||
|
|
||||||
footer: Object as PropType<VueNode>,
|
footer: Object as PropType<VueNode>,
|
||||||
|
|
||||||
getContainer: Function as PropType<() => any>,
|
getContainer: Function as PropType<() => any>,
|
||||||
|
|
||||||
mask: propTypes.bool.def(true),
|
mask: { type: Boolean, default: true },
|
||||||
|
|
||||||
maskClosable: propTypes.bool.def(true),
|
maskClosable: { type: Boolean, default: true },
|
||||||
keyboard: propTypes.bool.def(true),
|
keyboard: { type: Boolean, default: true },
|
||||||
|
|
||||||
maskStyle: Object as PropType<CSSProperties>,
|
maskStyle: Object as PropType<CSSProperties>,
|
||||||
|
|
||||||
okType: propTypes.string.def('primary'),
|
okType: { type: String, default: 'primary' },
|
||||||
|
|
||||||
okButtonProps: Object as PropType<ButtonProps>,
|
okButtonProps: Object as PropType<ButtonProps>,
|
||||||
|
|
||||||
cancelButtonProps: Object as PropType<ButtonProps>,
|
cancelButtonProps: Object as PropType<ButtonProps>,
|
||||||
|
|
||||||
title: propTypes.string,
|
title: { type: String },
|
||||||
|
|
||||||
visible: propTypes.bool,
|
visible: { type: Boolean },
|
||||||
|
|
||||||
width: [String, Number] as PropType<string | number>,
|
width: [String, Number] as PropType<string | number>,
|
||||||
|
|
||||||
wrapClassName: propTypes.string,
|
wrapClassName: { type: String },
|
||||||
|
|
||||||
zIndex: propTypes.number,
|
zIndex: { type: Number },
|
||||||
});
|
});
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
export { default as QrCode } from './src/Qrcode.vue';
|
import { withInstall } from '/@/utils';
|
||||||
|
import qrCode from './src/Qrcode.vue';
|
||||||
|
|
||||||
export * from './src/types';
|
export const QrCode = withInstall(qrCode);
|
||||||
|
export * from './src/typing';
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
import { toCanvas, QRCodeRenderersOptions, LogoType } from './qrcodePlus';
|
import { toCanvas, QRCodeRenderersOptions, LogoType } from './qrcodePlus';
|
||||||
import { toDataURL } from 'qrcode';
|
import { toDataURL } from 'qrcode';
|
||||||
import { downloadByUrl } from '/@/utils/file/download';
|
import { downloadByUrl } from '/@/utils/file/download';
|
||||||
import { QrcodeDoneEventParams } from './types';
|
import { QrcodeDoneEventParams } from './typing';
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'QrCode',
|
name: 'QrCode',
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { toCanvas } from 'qrcode';
|
import { toCanvas } from 'qrcode';
|
||||||
import type { QRCodeRenderersOptions } from 'qrcode';
|
import type { QRCodeRenderersOptions } from 'qrcode';
|
||||||
import { RenderQrCodeParams, ContentType } from './types';
|
import { RenderQrCodeParams, ContentType } from './typing';
|
||||||
export const renderQrCode = ({ canvas, content, width = 0, options = {} }: RenderQrCodeParams) => {
|
export const renderQrCode = ({ canvas, content, width = 0, options = {} }: RenderQrCodeParams) => {
|
||||||
// 容错率,默认对内容少的二维码采用高容错率,内容多的二维码采用低容错率
|
// 容错率,默认对内容少的二维码采用高容错率,内容多的二维码采用低容错率
|
||||||
options.errorCorrectionLevel = options.errorCorrectionLevel || getErrorCorrectionLevel(content);
|
options.errorCorrectionLevel = options.errorCorrectionLevel || getErrorCorrectionLevel(content);
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import { isString } from '/@/utils/is';
|
import { isString } from '/@/utils/is';
|
||||||
import { RenderQrCodeParams, LogoType } from './types';
|
import { RenderQrCodeParams, LogoType } from './typing';
|
||||||
export const drawLogo = ({ canvas, logo }: RenderQrCodeParams) => {
|
export const drawLogo = ({ canvas, logo }: RenderQrCodeParams) => {
|
||||||
if (!logo) {
|
if (!logo) {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
resolve((canvas as HTMLCanvasElement).toDataURL());
|
resolve((canvas as HTMLCanvasElement).toDataURL());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const canvasWidth = (canvas as HTMLCanvasElement).width;
|
const canvasWidth = (canvas as HTMLCanvasElement).width;
|
||||||
const {
|
const {
|
||||||
logoSize = 0.15,
|
logoSize = 0.15,
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
// 参考 qr-code-with-logo 进行ts版本修改
|
// 参考 qr-code-with-logo 进行ts版本修改
|
||||||
import { toCanvas } from './toCanvas';
|
import { toCanvas } from './toCanvas';
|
||||||
export * from './types';
|
export * from './typing';
|
||||||
|
|
||||||
export { toCanvas };
|
export { toCanvas };
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { renderQrCode } from './drawCanvas';
|
import { renderQrCode } from './drawCanvas';
|
||||||
import { drawLogo } from './drawLogo';
|
import { drawLogo } from './drawLogo';
|
||||||
import { RenderQrCodeParams } from './types';
|
import { RenderQrCodeParams } from './typing';
|
||||||
export const toCanvas = (options: RenderQrCodeParams) => {
|
export const toCanvas = (options: RenderQrCodeParams) => {
|
||||||
return renderQrCode(options)
|
return renderQrCode(options)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
|
@ -95,7 +95,7 @@
|
|||||||
&__entry {
|
&__entry {
|
||||||
position: relative;
|
position: relative;
|
||||||
//height: 240px;
|
//height: 240px;
|
||||||
padding: 130px 30px 60px 30px;
|
padding: 130px 30px 30px 30px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,10 +8,7 @@
|
|||||||
<Alert message="自适应高度/显示footer" show-icon />
|
<Alert message="自适应高度/显示footer" show-icon />
|
||||||
<a-button type="primary" class="my-4" @click="openDrawer3(true)"> 打开Drawer </a-button>
|
<a-button type="primary" class="my-4" @click="openDrawer3(true)"> 打开Drawer </a-button>
|
||||||
|
|
||||||
<Alert
|
<Alert message="内外数据交互" show-icon />
|
||||||
message="内外数据交互,外部通过 transferModalData 发送,内部通过 receiveDrawerDataRef 接收。该数据具有响应式"
|
|
||||||
show-icon
|
|
||||||
/>
|
|
||||||
<a-button type="primary" class="my-4" @click="send"> 打开Drawer并传递数据 </a-button>
|
<a-button type="primary" class="my-4" @click="send"> 打开Drawer并传递数据 </a-button>
|
||||||
<Alert message="详情页模式" show-icon />
|
<Alert message="详情页模式" show-icon />
|
||||||
<a-button type="primary" class="my-4" @click="openDrawer5(true)"> 打开详情Drawer </a-button>
|
<a-button type="primary" class="my-4" @click="openDrawer5(true)"> 打开详情Drawer </a-button>
|
||||||
|
@ -14,10 +14,7 @@
|
|||||||
<Alert message="自适应高度" show-icon />
|
<Alert message="自适应高度" show-icon />
|
||||||
<a-button type="primary" class="my-4" @click="openModal3"> 打开弹窗 </a-button>
|
<a-button type="primary" class="my-4" @click="openModal3"> 打开弹窗 </a-button>
|
||||||
|
|
||||||
<Alert
|
<Alert message="内外数据交互" show-icon />
|
||||||
message="内外数据交互,外部通过 transferModalData 发送,内部通过 receiveDrawerDataRef 接收。该数据具有响应式"
|
|
||||||
show-icon
|
|
||||||
/>
|
|
||||||
<a-button type="primary" class="my-4" @click="send"> 打开弹窗并传递数据 </a-button>
|
<a-button type="primary" class="my-4" @click="send"> 打开弹窗并传递数据 </a-button>
|
||||||
|
|
||||||
<Modal1 @register="register1" :minHeight="100" />
|
<Modal1 @register="register1" :minHeight="100" />
|
||||||
|
2
types/global.d.ts
vendored
2
types/global.d.ts
vendored
@ -1,6 +1,7 @@
|
|||||||
import type {
|
import type {
|
||||||
ComponentRenderProxy,
|
ComponentRenderProxy,
|
||||||
VNode,
|
VNode,
|
||||||
|
VNodeChild,
|
||||||
ComponentPublicInstance,
|
ComponentPublicInstance,
|
||||||
FunctionalComponent,
|
FunctionalComponent,
|
||||||
PropType as VuePropType,
|
PropType as VuePropType,
|
||||||
@ -23,6 +24,7 @@ declare global {
|
|||||||
|
|
||||||
// vue
|
// vue
|
||||||
declare type PropType<T> = VuePropType<T>;
|
declare type PropType<T> = VuePropType<T>;
|
||||||
|
declare type VueNode = VNodeChild | JSX.Element;
|
||||||
|
|
||||||
export type Writable<T> = {
|
export type Writable<T> = {
|
||||||
-readonly [P in keyof T]: T[P];
|
-readonly [P in keyof T]: T[P];
|
||||||
|
Loading…
Reference in New Issue
Block a user