fix(modal): ensure that the full screen height is calculated correctly

This commit is contained in:
Vben 2021-06-11 22:29:02 +08:00
parent 639520ad5d
commit 1c1755cf5b
25 changed files with 116 additions and 118 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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';

View File

@ -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';

View File

@ -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;
} }

View File

@ -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>;
}; };
}, },

View File

@ -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();

View File

@ -33,6 +33,7 @@
function handleCancel(e: Event) { function handleCancel(e: Event) {
emit('cancel', e); emit('cancel', e);
} }
return { handleOk, handleCancel }; return { handleOk, handleCancel };
}, },
}); });

View File

@ -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>

View File

@ -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(() => {

View File

@ -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(() => {

View File

@ -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);
}); });

View File

@ -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 },
}); });

View File

@ -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';

View File

@ -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',

View File

@ -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);

View File

@ -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,

View File

@ -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 };

View File

@ -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(() => {

View File

@ -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;
} }

View File

@ -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>

View File

@ -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
View File

@ -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];