feat: update modal

pull/2376/head
tangjinzhou 2020-06-15 23:47:49 +08:00
parent e2a7165508
commit 75e1661c16
7 changed files with 157 additions and 186 deletions

View File

@ -24,6 +24,7 @@ export default {
visible: PropTypes.bool,
},
data() {
this._component = null;
const { visible } = this.$props;
openCount = visible ? openCount + 1 : openCount;
return {};

View File

@ -3,10 +3,7 @@ import Dialog from './Modal';
import ActionButton from './ActionButton';
import { getConfirmLocale } from './locale';
export default {
functional: true,
render(h, context) {
const { props } = context;
const ConfirmDialog = (_, { attrs }) => {
const {
icon,
onCancel,
@ -22,29 +19,29 @@ export default {
okButtonProps,
cancelButtonProps,
closable = false,
} = props;
const okType = props.okType || 'primary';
const prefixCls = props.prefixCls || 'ant-modal';
} = attrs;
const okType = attrs.okType || 'primary';
const prefixCls = attrs.prefixCls || 'ant-modal';
const contentPrefixCls = `${prefixCls}-confirm`;
// true
const okCancel = 'okCancel' in props ? props.okCancel : true;
const width = props.width || 416;
const style = props.style || {};
const mask = props.mask === undefined ? true : props.mask;
const okCancel = 'okCancel' in attrs ? attrs.okCancel : true;
const width = attrs.width || 416;
const style = attrs.style || {};
const mask = attrs.mask === undefined ? true : attrs.mask;
// false
const maskClosable = props.maskClosable === undefined ? false : props.maskClosable;
const maskClosable = attrs.maskClosable === undefined ? false : attrs.maskClosable;
const runtimeLocale = getConfirmLocale();
const okText = props.okText || (okCancel ? runtimeLocale.okText : runtimeLocale.justOkText);
const cancelText = props.cancelText || runtimeLocale.cancelText;
const autoFocusButton = props.autoFocusButton === null ? false : props.autoFocusButton || 'ok';
const transitionName = props.transitionName || 'zoom';
const maskTransitionName = props.maskTransitionName || 'fade';
const okText = attrs.okText || (okCancel ? runtimeLocale.okText : runtimeLocale.justOkText);
const cancelText = attrs.cancelText || runtimeLocale.cancelText;
const autoFocusButton = attrs.autoFocusButton === null ? false : attrs.autoFocusButton || 'ok';
const transitionName = attrs.transitionName || 'zoom';
const maskTransitionName = attrs.maskTransitionName || 'fade';
const classString = classNames(
contentPrefixCls,
`${contentPrefixCls}-${props.type}`,
`${prefixCls}-${props.type}`,
props.class,
`${contentPrefixCls}-${attrs.type}`,
`${prefixCls}-${attrs.type}`,
attrs.class,
);
const cancelButton = okCancel && (
@ -83,12 +80,12 @@ export default {
>
<div class={`${contentPrefixCls}-body-wrapper`}>
<div class={`${contentPrefixCls}-body`}>
{typeof icon === 'function' ? icon(h) : icon}
{props.title === undefined ? null : (
<span class={`${contentPrefixCls}-title`}>{props.title}</span>
{typeof icon === 'function' ? icon() : icon}
{attrs.title === undefined ? null : (
<span class={`${contentPrefixCls}-title`}>{attrs.title}</span>
)}
<div class={`${contentPrefixCls}-content`}>
{typeof props.content === 'function' ? props.content(h) : props.content}
{typeof attrs.content === 'function' ? attrs.content() : attrs.content}
</div>
</div>
<div class={`${contentPrefixCls}-btns`}>
@ -106,5 +103,6 @@ export default {
</div>
</Dialog>
);
},
};
ConfirmDialog.inheritAttrs = false;
export default ConfirmDialog;

View File

@ -1,3 +1,4 @@
import { inject } from 'vue';
import classNames from 'classnames';
import Dialog from '../vc-dialog';
import PropTypes from '../_util/vue-types';
@ -8,14 +9,7 @@ import Button from '../button';
import buttonTypes from '../button/buttonTypes';
const ButtonType = buttonTypes().type;
import LocaleReceiver from '../locale-provider/LocaleReceiver';
import {
initDefaultProps,
getComponentFromProp,
getClass,
getStyle,
mergeProps,
getListeners,
} from '../_util/props-util';
import { initDefaultProps, getComponent, getSlot } from '../_util/props-util';
import { ConfigConsumerProps } from '../config-provider';
let mousePosition = null;
@ -116,8 +110,10 @@ export default {
this.sVisible = val;
},
},
inject: {
configProvider: { default: () => ConfigConsumerProps },
setup() {
return {
configProvider: inject('configProvider', ConfigConsumerProps),
};
},
// static info: ModalFunc;
// static success: ModalFunc;
@ -128,6 +124,7 @@ export default {
methods: {
handleCancel(e) {
this.$emit('cancel', e);
this.$emit('update:visible', false);
this.$emit('change', false);
},
@ -136,26 +133,19 @@ export default {
},
renderFooter(locale) {
const { okType, confirmLoading } = this;
const cancelBtnProps = mergeProps(
{ on: { click: this.handleCancel } },
this.cancelButtonProps || {},
);
const okBtnProps = mergeProps(
{
on: { click: this.handleOk },
props: {
const cancelBtnProps = { onClick: this.handleCancel, ...(this.cancelButtonProps || {}) };
const okBtnProps = {
onClick: this.handleOk,
type: okType,
loading: confirmLoading,
},
},
this.okButtonProps || {},
);
...(this.okButtonProps || {}),
};
return (
<div>
<Button {...cancelBtnProps}>
{getComponentFromProp(this, 'cancelText') || locale.cancelText}
{getComponent(this, 'cancelText') || locale.cancelText}
</Button>
<Button {...okBtnProps}>{getComponentFromProp(this, 'okText') || locale.okText}</Button>
<Button {...okBtnProps}>{getComponent(this, 'okText') || locale.okText}</Button>
</div>
);
},
@ -168,11 +158,9 @@ export default {
wrapClassName,
centered,
getContainer,
$slots,
$scopedSlots,
$attrs,
} = this;
const children = $scopedSlots.default ? $scopedSlots.default() : $slots.default;
const children = getSlot(this);
const { getPrefixCls, getPopupContainer: getContextPopupContainer } = this.configProvider;
const prefixCls = getPrefixCls('modal', customizePrefixCls);
@ -180,20 +168,20 @@ export default {
<LocaleReceiver
componentName="Modal"
defaultLocale={getConfirmLocale()}
scopedSlots={{ default: this.renderFooter }}
children={this.renderFooter}
/>
);
const closeIcon = getComponentFromProp(this, 'closeIcon');
const closeIcon = getComponent(this, 'closeIcon');
const closeIconToRender = (
<span class={`${prefixCls}-close-x`}>
{closeIcon || <CloseOutlined class={`${prefixCls}-close-icon`} />}
</span>
);
const footer = getComponentFromProp(this, 'footer');
const title = getComponentFromProp(this, 'title');
const footer = getComponent(this, 'footer');
const title = getComponent(this, 'title');
const dialogProps = {
props: {
...this.$props,
...$attrs,
getContainer: getContainer === undefined ? getContextPopupContainer : getContainer,
prefixCls,
wrapClassName: classNames({ [`${prefixCls}-centered`]: !!centered }, wrapClassName),
@ -202,14 +190,7 @@ export default {
visible,
mousePosition,
closeIcon: closeIconToRender,
},
on: {
...getListeners(this),
close: this.handleCancel,
},
class: getClass(this),
style: getStyle(this),
attrs: $attrs,
onClose: this.handleCancel,
};
return <Dialog {...dialogProps}>{children}</Dialog>;
},

View File

@ -1,7 +1,7 @@
import Vue from 'vue';
import { createApp } from 'vue';
import ConfirmDialog from './ConfirmDialog';
import { destroyFns } from './Modal';
import Base from '../base';
import Omit from 'omit.js';
export default function confirm(config) {
@ -12,7 +12,7 @@ export default function confirm(config) {
let currentConfig = { ...Omit(config, ['parentContext']), close, visible: true };
let confirmDialogInstance = null;
const confirmDialogProps = { props: {} };
let confirmDialogProps = {};
function close(...args) {
destroy(...args);
}
@ -21,11 +21,11 @@ export default function confirm(config) {
...currentConfig,
...newConfig,
};
confirmDialogProps.props = currentConfig;
Object.assign(confirmDialogInstance, currentConfig);
}
function destroy(...args) {
if (confirmDialogInstance && div.parentNode) {
confirmDialogInstance.$destroy();
confirmDialogInstance.unmount(div);
confirmDialogInstance = null;
div.parentNode.removeChild(div);
}
@ -43,10 +43,8 @@ export default function confirm(config) {
}
function render(props) {
confirmDialogProps.props = props;
const V = Base.Vue || Vue;
return new V({
el,
confirmDialogProps = props;
return createApp({
parent: config.parentContext,
data() {
return { confirmDialogProps };
@ -56,7 +54,7 @@ export default function confirm(config) {
const cdProps = { ...this.confirmDialogProps };
return <ConfirmDialog {...cdProps} />;
},
});
}).mount(el);
}
confirmDialogInstance = render(currentConfig);

View File

@ -4,7 +4,6 @@ import InfoCircleOutlined from '@ant-design/icons-vue/InfoCircleOutlined';
import CheckCircleOutlined from '@ant-design/icons-vue/CheckCircleOutlined';
import CloseCircleOutlined from '@ant-design/icons-vue/CloseCircleOutlined';
import ExclamationCircleOutlined from '@ant-design/icons-vue/ExclamationCircleOutlined';
import Base from '../base';
// export { ActionButtonProps } from './ActionButton'
// export { ModalProps, ModalFuncProps } from './Modal'
@ -12,9 +11,7 @@ import Base from '../base';
const info = function(props) {
const config = {
type: 'info',
icon: h => {
return <InfoCircleOutlined />;
},
icon: <InfoCircleOutlined />,
okCancel: false,
...props,
};
@ -24,9 +21,7 @@ const info = function(props) {
const success = function(props) {
const config = {
type: 'success',
icon: h => {
return <CheckCircleOutlined />;
},
icon: <CheckCircleOutlined />,
okCancel: false,
...props,
};
@ -36,9 +31,7 @@ const success = function(props) {
const error = function(props) {
const config = {
type: 'error',
icon: h => {
return <CloseCircleOutlined />;
},
icon: <CloseCircleOutlined />,
okCancel: false,
...props,
};
@ -48,9 +41,7 @@ const error = function(props) {
const warning = function(props) {
const config = {
type: 'warning',
icon: h => {
return <ExclamationCircleOutlined />;
},
icon: <ExclamationCircleOutlined />,
okCancel: false,
...props,
};
@ -83,9 +74,8 @@ Modal.destroyAll = function destroyAllFn() {
};
/* istanbul ignore next */
Modal.install = function(Vue) {
Vue.use(Base);
Vue.component(Modal.name, Modal);
Modal.install = function(app) {
app.component(Modal.name, Modal);
};
export default Modal;

View File

@ -1,5 +1,5 @@
import { provide, Transition } from 'vue';
import { initDefaultProps } from '../_util/props-util';
import { initDefaultProps, getSlot } from '../_util/props-util';
import KeyCode from '../_util/KeyCode';
import contains from '../vc-util/Dom/contains';
import LazyRenderBox from './LazyRenderBox';
@ -49,6 +49,7 @@ function offset(el) {
let cacheOverflow = {};
export default {
name: 'VcDialog',
mixins: [BaseMixin],
props: initDefaultProps(IDialogPropTypes, {
mask: true,
@ -64,6 +65,9 @@ export default {
data() {
return {
destroyPopup: false,
inTransition: false,
titleId: `rcDialogTitle${uuid++}`,
dialogMouseDown: undefined,
};
},
@ -80,11 +84,6 @@ export default {
created() {
provide('dialogContext', this);
},
beforeMount() {
this.inTransition = false;
this.titleId = `rcDialogTitle${uuid++}`;
},
mounted() {
this.$nextTick(() => {
this.updatedCallback(false);
@ -285,7 +284,7 @@ export default {
{closer}
{header}
<div key="body" class={`${prefixCls}-body`} style={bodyStyle} ref="body" {...bodyProps}>
{this.$slots.default}
{getSlot(this)}
</div>
{footer}
</div>
@ -320,22 +319,24 @@ export default {
let maskElement;
if (props.mask) {
const maskTransition = this.getMaskTransitionName();
maskElement = (
const tempMaskElement = (
<LazyRenderBox
v-show={props.visible}
style={this.getMaskStyle()}
key="mask"
class={`${props.prefixCls}-mask`}
{...props.maskProps}
{...(props.maskProps || {})}
/>
);
if (maskTransition) {
const maskTransitionProps = getTransitionProps(maskTransition);
maskElement = (
<Transition key="mask" {...maskTransitionProps}>
{maskElement}
{tempMaskElement}
</Transition>
);
} else {
maskElement = tempMaskElement;
}
}
return maskElement;

View File

@ -28,6 +28,7 @@ import Popconfirm from 'ant-design-vue/popconfirm';
import Popover from 'ant-design-vue/popover';
import notification from 'ant-design-vue/notification';
import message from 'ant-design-vue/message';
import Modal from 'ant-design-vue/modal';
import 'ant-design-vue/style.js';
const app = createApp(App);
@ -59,4 +60,5 @@ app
.use(Tag)
.use(Popconfirm)
.use(Popover)
.use(Modal)
.mount('#app');