From 11498add8e92c434c799cc72b3294e50a62c7a2f Mon Sep 17 00:00:00 2001 From: undefined Date: Wed, 8 Sep 2021 17:12:11 +0800 Subject: [PATCH] fix: appcontext not work & function support #4627 --- components/modal/ConfirmDialog.tsx | 27 +++++++++++++----- components/modal/Modal.tsx | 13 +++++---- components/modal/confirm.tsx | 44 ++++++++++++++++-------------- components/modal/index.tsx | 8 +++--- v2-doc | 2 +- 5 files changed, 56 insertions(+), 38 deletions(-) diff --git a/components/modal/ConfirmDialog.tsx b/components/modal/ConfirmDialog.tsx index 21414a15c..6de31a8c3 100644 --- a/components/modal/ConfirmDialog.tsx +++ b/components/modal/ConfirmDialog.tsx @@ -3,14 +3,21 @@ import type { ModalFuncProps } from './Modal'; import Dialog from './Modal'; import ActionButton from './ActionButton'; import { getConfirmLocale } from './locale'; -import type { FunctionalComponent } from 'vue'; +import { FunctionalComponent } from 'vue'; interface ConfirmDialogProps extends ModalFuncProps { afterClose?: () => void; - close: (...args: any[]) => void; + close?: (...args: any[]) => void; autoFocusButton?: null | 'ok' | 'cancel'; } +function renderSomeContent(_name, someContent) { + if (typeof someContent === 'function') { + return someContent(); + } + return someContent; +} + const ConfirmDialog: FunctionalComponent = props => { const { icon, @@ -40,8 +47,10 @@ const ConfirmDialog: FunctionalComponent = props => { // 默认为 false,保持旧版默认行为 const maskClosable = props.maskClosable === undefined ? false : props.maskClosable; const runtimeLocale = getConfirmLocale(); - const okText = props.okText || (okCancel ? runtimeLocale.okText : runtimeLocale.justOkText); - const cancelText = props.cancelText || runtimeLocale.cancelText; + const okText = + renderSomeContent('okText', props.okText) || + (okCancel ? runtimeLocale.okText : runtimeLocale.justOkText); + const cancelText = renderSomeContent('cancelText', props.cancelText) || runtimeLocale.cancelText; const autoFocusButton = props.autoFocusButton === null ? false : props.autoFocusButton || 'ok'; const transitionName = props.transitionName || 'zoom'; const maskTransitionName = props.maskTransitionName || 'fade'; @@ -89,11 +98,15 @@ const ConfirmDialog: FunctionalComponent = props => { >
- {icon} + {renderSomeContent('icon', icon)} {props.title === undefined ? null : ( - {props.title} + + {renderSomeContent('title', props.title)} + )} -
{props.content}
+
+ {renderSomeContent('content', props.content)} +
{cancelButton} diff --git a/components/modal/Modal.tsx b/components/modal/Modal.tsx index 1b3fbc02e..db74db4df 100644 --- a/components/modal/Modal.tsx +++ b/components/modal/Modal.tsx @@ -95,9 +95,9 @@ export interface ModalFuncProps { prefixCls?: string; class?: string; visible?: boolean; - title?: VNodeTypes; + title?: () => VNodeTypes | VNodeTypes; closable?: boolean; - content?: VNodeTypes; + content?: () => VNodeTypes | VNodeTypes; // TODO: find out exact types onOk?: (...args: any[]) => any; onCancel?: (...args: any[]) => any; @@ -105,10 +105,10 @@ export interface ModalFuncProps { cancelButtonProps?: ButtonPropsType; centered?: boolean; width?: string | number; - okText?: VNodeTypes; + okText?: () => VNodeTypes | VNodeTypes; okType?: LegacyButtonType; - cancelText?: VNodeTypes; - icon?: VNodeTypes; + cancelText?: () => VNodeTypes | VNodeTypes; + icon?: () => VNodeTypes | VNodeTypes; /* Deprecated */ iconType?: string; mask?: boolean; @@ -123,7 +123,10 @@ export interface ModalFuncProps { autoFocusButton?: null | 'ok' | 'cancel'; transitionName?: string; maskTransitionName?: string; + + /** @deprecated please use `appContext` instead */ parentContext?: any; + appContext?: any; } type getContainerFunc = () => HTMLElement; diff --git a/components/modal/confirm.tsx b/components/modal/confirm.tsx index 91c8efa07..053dd99fd 100644 --- a/components/modal/confirm.tsx +++ b/components/modal/confirm.tsx @@ -1,17 +1,20 @@ -import { createApp } from 'vue'; +import { createVNode, render as vueRender } from 'vue'; import ConfirmDialog from './ConfirmDialog'; import type { ModalFuncProps } from './Modal'; import { destroyFns } from './Modal'; import Omit from 'omit.js'; -export default function confirm(config: ModalFuncProps) { +const confirm = (config: ModalFuncProps) => { const div = document.createElement('div'); document.body.appendChild(div); - let currentConfig = { ...Omit(config, ['parentContext']), close, visible: true } as any; + let currentConfig = { + ...Omit(config, ['parentContext', 'appContext']), + close, + visible: true, + } as any; let confirmDialogInstance = null; - let confirmDialogProps = {}; function close(this: typeof close, ...args: any[]) { currentConfig = { ...currentConfig, @@ -25,12 +28,15 @@ export default function confirm(config: ModalFuncProps) { ...currentConfig, ...newConfig, }; - confirmDialogInstance && - Object.assign(confirmDialogInstance, { confirmDialogProps: currentConfig }); + if (confirmDialogInstance) { + Object.assign(confirmDialogInstance.component.props, currentConfig); + confirmDialogInstance.component.update(); + } } function destroy(...args: any[]) { if (confirmDialogInstance && div.parentNode) { - confirmDialogInstance.vIf = false; // hack destroy + Object.assign(confirmDialogInstance.component.props, { vIf: false }); // hack destroy + confirmDialogInstance.component.update(); confirmDialogInstance = null; div.parentNode.removeChild(div); } @@ -46,20 +52,14 @@ export default function confirm(config: ModalFuncProps) { } } } - + const Wrapper = p => { + return p.vIf ? : null; + }; function render(props: ModalFuncProps) { - confirmDialogProps = props; - return createApp({ - parent: (config as any).parentContext, - data() { - return { confirmDialogProps, vIf: true }; - }, - render() { - // 先解构,避免报错,原因不详 - const cdProps = { ...this.confirmDialogProps }; - return this.vIf ? : null; - }, - }).mount(div); + const vm = createVNode(Wrapper, { ...props, vIf: true }); + vm.appContext = config.parentContext || config.appContext || vm.appContext; + vueRender(vm, div); + return vm; } confirmDialogInstance = render(currentConfig); @@ -68,4 +68,6 @@ export default function confirm(config: ModalFuncProps) { destroy: close, update, }; -} +}; + +export default confirm; diff --git a/components/modal/index.tsx b/components/modal/index.tsx index f2533f17c..7ef994915 100644 --- a/components/modal/index.tsx +++ b/components/modal/index.tsx @@ -13,7 +13,7 @@ export { ModalProps, ModalFuncProps } from './Modal'; const info = function (props: ModalFuncProps) { const config = { type: 'info', - icon: , + icon: () => , okCancel: false, ...props, }; @@ -23,7 +23,7 @@ const info = function (props: ModalFuncProps) { const success = function (props: ModalFuncProps) { const config = { type: 'success', - icon: , + icon: () => , okCancel: false, ...props, }; @@ -33,7 +33,7 @@ const success = function (props: ModalFuncProps) { const error = function (props: ModalFuncProps) { const config = { type: 'error', - icon: , + icon: () => , okCancel: false, ...props, }; @@ -43,7 +43,7 @@ const error = function (props: ModalFuncProps) { const warning = function (props: ModalFuncProps) { const config = { type: 'warning', - icon: , + icon: () => , okCancel: false, ...props, }; diff --git a/v2-doc b/v2-doc index 371725ede..781e3a331 160000 --- a/v2-doc +++ b/v2-doc @@ -1 +1 @@ -Subproject commit 371725edee4a3af9d21b50bba5faf37594d16279 +Subproject commit 781e3a331a2d62ab4fa4d5e903a7410dfa752c1e