fix: appcontext not work & function support #4627

pull/4632/head
undefined 2021-09-08 17:12:11 +08:00
parent 9cd4783fd5
commit 11498add8e
5 changed files with 56 additions and 38 deletions

View File

@ -3,14 +3,21 @@ import type { ModalFuncProps } from './Modal';
import Dialog from './Modal'; import Dialog from './Modal';
import ActionButton from './ActionButton'; import ActionButton from './ActionButton';
import { getConfirmLocale } from './locale'; import { getConfirmLocale } from './locale';
import type { FunctionalComponent } from 'vue'; import { FunctionalComponent } from 'vue';
interface ConfirmDialogProps extends ModalFuncProps { interface ConfirmDialogProps extends ModalFuncProps {
afterClose?: () => void; afterClose?: () => void;
close: (...args: any[]) => void; close?: (...args: any[]) => void;
autoFocusButton?: null | 'ok' | 'cancel'; autoFocusButton?: null | 'ok' | 'cancel';
} }
function renderSomeContent(_name, someContent) {
if (typeof someContent === 'function') {
return someContent();
}
return someContent;
}
const ConfirmDialog: FunctionalComponent<ConfirmDialogProps> = props => { const ConfirmDialog: FunctionalComponent<ConfirmDialogProps> = props => {
const { const {
icon, icon,
@ -40,8 +47,10 @@ const ConfirmDialog: FunctionalComponent<ConfirmDialogProps> = props => {
// false // false
const maskClosable = props.maskClosable === undefined ? false : props.maskClosable; const maskClosable = props.maskClosable === undefined ? false : props.maskClosable;
const runtimeLocale = getConfirmLocale(); const runtimeLocale = getConfirmLocale();
const okText = props.okText || (okCancel ? runtimeLocale.okText : runtimeLocale.justOkText); const okText =
const cancelText = props.cancelText || runtimeLocale.cancelText; 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 autoFocusButton = props.autoFocusButton === null ? false : props.autoFocusButton || 'ok';
const transitionName = props.transitionName || 'zoom'; const transitionName = props.transitionName || 'zoom';
const maskTransitionName = props.maskTransitionName || 'fade'; const maskTransitionName = props.maskTransitionName || 'fade';
@ -89,11 +98,15 @@ const ConfirmDialog: FunctionalComponent<ConfirmDialogProps> = props => {
> >
<div class={`${contentPrefixCls}-body-wrapper`}> <div class={`${contentPrefixCls}-body-wrapper`}>
<div class={`${contentPrefixCls}-body`}> <div class={`${contentPrefixCls}-body`}>
{icon} {renderSomeContent('icon', icon)}
{props.title === undefined ? null : ( {props.title === undefined ? null : (
<span class={`${contentPrefixCls}-title`}>{props.title}</span> <span class={`${contentPrefixCls}-title`}>
{renderSomeContent('title', props.title)}
</span>
)} )}
<div class={`${contentPrefixCls}-content`}>{props.content}</div> <div class={`${contentPrefixCls}-content`}>
{renderSomeContent('content', props.content)}
</div>
</div> </div>
<div class={`${contentPrefixCls}-btns`}> <div class={`${contentPrefixCls}-btns`}>
{cancelButton} {cancelButton}

View File

@ -95,9 +95,9 @@ export interface ModalFuncProps {
prefixCls?: string; prefixCls?: string;
class?: string; class?: string;
visible?: boolean; visible?: boolean;
title?: VNodeTypes; title?: () => VNodeTypes | VNodeTypes;
closable?: boolean; closable?: boolean;
content?: VNodeTypes; content?: () => VNodeTypes | VNodeTypes;
// TODO: find out exact types // TODO: find out exact types
onOk?: (...args: any[]) => any; onOk?: (...args: any[]) => any;
onCancel?: (...args: any[]) => any; onCancel?: (...args: any[]) => any;
@ -105,10 +105,10 @@ export interface ModalFuncProps {
cancelButtonProps?: ButtonPropsType; cancelButtonProps?: ButtonPropsType;
centered?: boolean; centered?: boolean;
width?: string | number; width?: string | number;
okText?: VNodeTypes; okText?: () => VNodeTypes | VNodeTypes;
okType?: LegacyButtonType; okType?: LegacyButtonType;
cancelText?: VNodeTypes; cancelText?: () => VNodeTypes | VNodeTypes;
icon?: VNodeTypes; icon?: () => VNodeTypes | VNodeTypes;
/* Deprecated */ /* Deprecated */
iconType?: string; iconType?: string;
mask?: boolean; mask?: boolean;
@ -123,7 +123,10 @@ export interface ModalFuncProps {
autoFocusButton?: null | 'ok' | 'cancel'; autoFocusButton?: null | 'ok' | 'cancel';
transitionName?: string; transitionName?: string;
maskTransitionName?: string; maskTransitionName?: string;
/** @deprecated please use `appContext` instead */
parentContext?: any; parentContext?: any;
appContext?: any;
} }
type getContainerFunc = () => HTMLElement; type getContainerFunc = () => HTMLElement;

View File

@ -1,17 +1,20 @@
import { createApp } from 'vue'; import { createVNode, render as vueRender } from 'vue';
import ConfirmDialog from './ConfirmDialog'; import ConfirmDialog from './ConfirmDialog';
import type { ModalFuncProps } from './Modal'; import type { ModalFuncProps } from './Modal';
import { destroyFns } from './Modal'; import { destroyFns } from './Modal';
import Omit from 'omit.js'; import Omit from 'omit.js';
export default function confirm(config: ModalFuncProps) { const confirm = (config: ModalFuncProps) => {
const div = document.createElement('div'); const div = document.createElement('div');
document.body.appendChild(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 confirmDialogInstance = null;
let confirmDialogProps = {};
function close(this: typeof close, ...args: any[]) { function close(this: typeof close, ...args: any[]) {
currentConfig = { currentConfig = {
...currentConfig, ...currentConfig,
@ -25,12 +28,15 @@ export default function confirm(config: ModalFuncProps) {
...currentConfig, ...currentConfig,
...newConfig, ...newConfig,
}; };
confirmDialogInstance && if (confirmDialogInstance) {
Object.assign(confirmDialogInstance, { confirmDialogProps: currentConfig }); Object.assign(confirmDialogInstance.component.props, currentConfig);
confirmDialogInstance.component.update();
}
} }
function destroy(...args: any[]) { function destroy(...args: any[]) {
if (confirmDialogInstance && div.parentNode) { if (confirmDialogInstance && div.parentNode) {
confirmDialogInstance.vIf = false; // hack destroy Object.assign(confirmDialogInstance.component.props, { vIf: false }); // hack destroy
confirmDialogInstance.component.update();
confirmDialogInstance = null; confirmDialogInstance = null;
div.parentNode.removeChild(div); div.parentNode.removeChild(div);
} }
@ -46,20 +52,14 @@ export default function confirm(config: ModalFuncProps) {
} }
} }
} }
const Wrapper = p => {
return p.vIf ? <ConfirmDialog {...p}></ConfirmDialog> : null;
};
function render(props: ModalFuncProps) { function render(props: ModalFuncProps) {
confirmDialogProps = props; const vm = createVNode(Wrapper, { ...props, vIf: true });
return createApp({ vm.appContext = config.parentContext || config.appContext || vm.appContext;
parent: (config as any).parentContext, vueRender(vm, div);
data() { return vm;
return { confirmDialogProps, vIf: true };
},
render() {
//
const cdProps = { ...this.confirmDialogProps };
return this.vIf ? <ConfirmDialog {...cdProps} /> : null;
},
}).mount(div);
} }
confirmDialogInstance = render(currentConfig); confirmDialogInstance = render(currentConfig);
@ -68,4 +68,6 @@ export default function confirm(config: ModalFuncProps) {
destroy: close, destroy: close,
update, update,
}; };
} };
export default confirm;

View File

@ -13,7 +13,7 @@ export { ModalProps, ModalFuncProps } from './Modal';
const info = function (props: ModalFuncProps) { const info = function (props: ModalFuncProps) {
const config = { const config = {
type: 'info', type: 'info',
icon: <InfoCircleOutlined />, icon: () => <InfoCircleOutlined />,
okCancel: false, okCancel: false,
...props, ...props,
}; };
@ -23,7 +23,7 @@ const info = function (props: ModalFuncProps) {
const success = function (props: ModalFuncProps) { const success = function (props: ModalFuncProps) {
const config = { const config = {
type: 'success', type: 'success',
icon: <CheckCircleOutlined />, icon: () => <CheckCircleOutlined />,
okCancel: false, okCancel: false,
...props, ...props,
}; };
@ -33,7 +33,7 @@ const success = function (props: ModalFuncProps) {
const error = function (props: ModalFuncProps) { const error = function (props: ModalFuncProps) {
const config = { const config = {
type: 'error', type: 'error',
icon: <CloseCircleOutlined />, icon: () => <CloseCircleOutlined />,
okCancel: false, okCancel: false,
...props, ...props,
}; };
@ -43,7 +43,7 @@ const error = function (props: ModalFuncProps) {
const warning = function (props: ModalFuncProps) { const warning = function (props: ModalFuncProps) {
const config = { const config = {
type: 'warning', type: 'warning',
icon: <ExclamationCircleOutlined />, icon: () => <ExclamationCircleOutlined />,
okCancel: false, okCancel: false,
...props, ...props,
}; };

2
v2-doc

@ -1 +1 @@
Subproject commit 371725edee4a3af9d21b50bba5faf37594d16279 Subproject commit 781e3a331a2d62ab4fa4d5e903a7410dfa752c1e