diff --git a/components/align/Align.vue b/components/align/Align.vue index f4cdf0bb1..c85af8120 100644 --- a/components/align/Align.vue +++ b/components/align/Align.vue @@ -2,6 +2,7 @@ import PropTypes from '../_util/vue-types' import align from 'dom-align' import clonedeep from 'lodash.clonedeep' +import isEqual from 'lodash.isequal' import addEventListener from '../_util/Dom/addEventListener' import { cloneElement } from '../_util/vnode.js' import isWindow from './isWindow' @@ -37,48 +38,47 @@ export default { monitorWindowResize: PropTypes.bool.def(false), disabled: PropTypes.bool.def(false), }, - watch: { - '$props': { - handler: function (props) { - const prevProps = this.prevProps - this.$nextTick(() => { - let reAlign = false - if (!props.disabled) { - if (prevProps.disabled || prevProps.align !== props.align) { - reAlign = true - } else { - const lastTarget = prevProps.target() - const currentTarget = props.target() - if (isWindow(lastTarget) && isWindow(currentTarget)) { - reAlign = false - } else if (lastTarget !== currentTarget) { - reAlign = true - } - } - } - - if (reAlign) { - this.forceAlign() - } - - if (props.monitorWindowResize && !props.disabled) { - this.startMonitorWindowResize() - } else { - this.stopMonitorWindowResize() - } - }) - }, - deep: true, - }, + data () { + return { + aligned: false, + } }, mounted () { const props = this.$props // if parent ref not attached .... use document.getElementById - this.forceAlign() + !this.aligned && this.forceAlign() if (!props.disabled && props.monitorWindowResize) { this.startMonitorWindowResize() } }, + updated () { + const prevProps = this.prevProps + const props = this.$props + let reAlign = false + if (!props.disabled) { + if (prevProps.disabled || !isEqual(prevProps.align, props.align)) { + reAlign = true + } else { + const lastTarget = prevProps.target() + const currentTarget = props.target() + if (isWindow(lastTarget) && isWindow(currentTarget)) { + reAlign = false + } else if (lastTarget !== currentTarget) { + reAlign = true + } + } + } + + if (reAlign) { + this.forceAlign() + } + + if (props.monitorWindowResize && !props.disabled) { + this.startMonitorWindowResize() + } else { + this.stopMonitorWindowResize() + } + }, beforeDestroy () { this.stopMonitorWindowResize() }, @@ -102,6 +102,7 @@ export default { const props = this.$props if (!props.disabled) { const source = this.$el + this.aligned = true // this.$emit('align', source, align(source, props.target(), props.align)) this.$listeners.align && this.$listeners.align(source, align(source, props.target(), props.align)) } diff --git a/components/button/button.vue b/components/button/button.vue index e82a87c07..016e3489d 100644 --- a/components/button/button.vue +++ b/components/button/button.vue @@ -3,12 +3,13 @@ import Icon from '../icon' const rxTwoCNChar = /^[\u4e00-\u9fa5]{2}$/ const isTwoCNChar = rxTwoCNChar.test.bind(rxTwoCNChar) import buttonTypes from './buttonTypes' +const props = buttonTypes() export default { name: 'Button', __ANT_BUTTON: true, components: { Icon }, props: { - ...buttonTypes, + ...props, }, data () { return { diff --git a/components/button/buttonTypes.js b/components/button/buttonTypes.js index 2104f1aa7..478fac2c6 100644 --- a/components/button/buttonTypes.js +++ b/components/button/buttonTypes.js @@ -1,5 +1,5 @@ import PropTypes from '../_util/vue-types' -export default { +export default () => ({ prefixCls: PropTypes.string.def('ant-btn'), type: PropTypes.oneOf(['primary', 'danger', 'dashed', 'ghost', 'default']).def('default'), htmlType: PropTypes.oneOf(['button', 'submit', 'reset']).def('button'), @@ -9,4 +9,4 @@ export default { loading: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]), disabled: PropTypes.bool, ghost: PropTypes.bool, -} +}) diff --git a/components/menu/src/SubMenu.vue b/components/menu/src/SubMenu.vue index 071999cac..1057c4601 100644 --- a/components/menu/src/SubMenu.vue +++ b/components/menu/src/SubMenu.vue @@ -415,6 +415,7 @@ export default { animProps.name = openTransitionName } else if (typeof openAnimation === 'object') { animProps = { ...animProps, ...openAnimation.props || {}} + animProps.on = openAnimation.on if (!transitionAppear) { animProps.appear = false } diff --git a/components/popconfirm/demo/dynamic-trigger.vue b/components/popconfirm/demo/dynamic-trigger.vue new file mode 100644 index 000000000..d2a6a4f40 --- /dev/null +++ b/components/popconfirm/demo/dynamic-trigger.vue @@ -0,0 +1,62 @@ + + + diff --git a/components/popconfirm/demo/index.vue b/components/popconfirm/demo/index.vue new file mode 100644 index 000000000..fefe4406f --- /dev/null +++ b/components/popconfirm/demo/index.vue @@ -0,0 +1,26 @@ + + diff --git a/components/popconfirm/demo/local.vue b/components/popconfirm/demo/local.vue new file mode 100644 index 000000000..a160786dd --- /dev/null +++ b/components/popconfirm/demo/local.vue @@ -0,0 +1,20 @@ + + + diff --git a/components/popconfirm/demo/placement.vue b/components/popconfirm/demo/placement.vue new file mode 100644 index 000000000..8efb91b96 --- /dev/null +++ b/components/popconfirm/demo/placement.vue @@ -0,0 +1,153 @@ + + + + diff --git a/components/popconfirm/index.vue b/components/popconfirm/index.vue index 9807ce386..a7286448a 100644 --- a/components/popconfirm/index.vue +++ b/components/popconfirm/index.vue @@ -9,23 +9,30 @@ import buttonTypes from '../button/buttonTypes' import Icon from '../icon' import Button from '../button' +const tooltipProps = abstractTooltipProps() +const btnProps = buttonTypes() export default { name: 'popconfirm', props: { - ...abstractTooltipProps, + ...tooltipProps, prefixCls: PropTypes.string.def('ant-popover'), transitionName: PropTypes.string.def('zoom-big'), content: PropTypes.any, title: PropTypes.any, - trigger: abstractTooltipProps.trigger.def('click'), - okType: buttonTypes.type.def('primary'), + trigger: tooltipProps.trigger.def('click'), + okType: btnProps.type.def('primary'), okText: PropTypes.any, cancelText: PropTypes.any, }, mixins: [BaseMixin], model: { prop: 'visible', - event: 'change', + event: 'visibleChange', + }, + watch: { + visible (val) { + this.sVisible = val + }, }, data () { return { @@ -48,16 +55,10 @@ export default { }, setVisible (sVisible) { - const props = this.$props if (!hasProp(this, 'visible')) { this.setState({ sVisible }) } - - const { onVisibleChange } = props - if (onVisibleChange) { - onVisibleChange(sVisible) - } - this.$emit('change', sVisible) + this.$emit('visibleChange', sVisible) }, getPopupDomNode () { return this.$refs.tooltip.getPopupDomNode() diff --git a/components/popover/index.vue b/components/popover/index.vue index 1089d6f0f..8fa4515e2 100644 --- a/components/popover/index.vue +++ b/components/popover/index.vue @@ -24,7 +24,7 @@ export default { }, render (h) { - const { title, prefixCls, content, $slots } = this + const { title, prefixCls, $slots } = this const props = getOptionProps(this) delete props.title delete props.content diff --git a/components/tooltip/abstractTooltipProps.js b/components/tooltip/abstractTooltipProps.js index 9faf70877..967d765b0 100644 --- a/components/tooltip/abstractTooltipProps.js +++ b/components/tooltip/abstractTooltipProps.js @@ -1,5 +1,5 @@ import PropTypes from '../_util/vue-types' -export default { +export default () => ({ trigger: PropTypes.oneOf(['hover', 'focus', 'click']).def('hover'), visible: PropTypes.bool, placement: PropTypes.oneOf(['top', 'left', 'right', 'bottom', @@ -16,4 +16,4 @@ export default { getPopupContainer: PropTypes.func, arrowPointAtCenter: PropTypes.bool.def(false), autoAdjustOverflow: PropTypes.oneOfType([PropTypes.bool, PropTypes.object]).def(true), -} +}) diff --git a/components/tooltip/tooltip.vue b/components/tooltip/tooltip.vue index c66fd4730..f6431a3bc 100644 --- a/components/tooltip/tooltip.vue +++ b/components/tooltip/tooltip.vue @@ -17,11 +17,11 @@ const splitObject = (obj, keys) => { }) return { picked, omited } } - +const props = abstractTooltipProps() export default { name: 'Tooltip', props: { - ...abstractTooltipProps, + ...props, title: PropTypes.any, }, model: { diff --git a/components/trigger/Popup.vue b/components/trigger/Popup.vue index 4587ad612..701227e6f 100644 --- a/components/trigger/Popup.vue +++ b/components/trigger/Popup.vue @@ -4,6 +4,7 @@ import Align from '../align' import PopupInner from './PopupInner' import LazyRenderBox from './LazyRenderBox' import { noop } from './utils' +import animate from 'css-animation' export default { props: { @@ -24,6 +25,7 @@ export default { }, data () { return { + aligned: false, destroyPopup: false, initAlign: false, // mounted之后再实例化align,即改变this.$el位置后实例化 } @@ -48,7 +50,8 @@ export default { initAlign (val) { if (val) { this.$nextTick(() => { - this.$refs.alignInstance.forceAlign() + // console.log(this.$refs.alignInstance.$el) + // this.$refs.alignInstance.forceAlign() }) } }, @@ -94,11 +97,6 @@ export default { getClassName (currentAlignClassName) { return `${this.$props.prefixCls} ${this.$props.popupClassName} ${currentAlignClassName}` }, - afterLeave (el) { - if (this.destroyPopupOnHide) { - this.destroyPopup = true - } - }, getPopupElement () { const { $props: props, $slots, $listeners } = this const { align, visible, prefixCls, animation } = props @@ -114,6 +112,7 @@ export default { props: { prefixCls, visible, + // hiddenClassName, }, class: `${className}`, on: { @@ -126,11 +125,43 @@ export default { const transitionProps = { props: Object.assign({ appear: true, - }, typeof animation === 'object' ? animation : { name: this.getTransitionName() }), + css: false, + }), + } + let opacity = '1' + const transitionEvent = { + beforeEnter: (el) => { + opacity = el.style.opacity + el.style.opacity = '0' + !this.aligned && this.$refs.alignInstance.forceAlign() + this.aligned = true + }, + enter: (el, done) => { + el.style.opacity = opacity + animate(el, 'zoom-big-enter', done) + }, + leave: (el, done) => { + animate(el, 'zoom-big-leave', done) + }, + afterLeave: (el) => { + if (this.destroyPopupOnHide) { + this.destroyPopup = true + } + }, + } + + if (typeof animation === 'object') { + const { on = {}, ...otherProps } = animation + transitionProps.props = { ...transitionProps.props, ...otherProps } + transitionProps.on = { ...on, afterLeave: (el) => { + transitionEvent.afterLeave(el) + on.afterLeave && on.afterLeave(el) + } } + } else { + transitionProps.on = transitionEvent } return ( +
{this.$slots.default} diff --git a/components/trigger/Transition.vue b/components/trigger/Transition.vue new file mode 100644 index 000000000..9b32f1314 --- /dev/null +++ b/components/trigger/Transition.vue @@ -0,0 +1,16 @@ + diff --git a/package.json b/package.json index fe8012171..2a87773ca 100644 --- a/package.json +++ b/package.json @@ -81,6 +81,7 @@ "eslint-plugin-vue": "^3.13.0", "lodash.clonedeep": "^4.5.0", "lodash.debounce": "^4.0.8", + "lodash.isequal": "^4.5.0", "lodash.isplainobject": "^4.0.6", "omit.js": "^1.0.0", "vue": "^2.5.13",