From b9fe97068234d8654ae160c261b6daf95f1dfef6 Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Tue, 26 Dec 2017 19:04:28 +0800 Subject: [PATCH] fix --- components/_util/vnode.js | 9 +- components/_util/warning.js | 5 +- components/align/Align.vue | 2 +- components/align/demo/simple.vue | 2 +- components/input/Input.vue | 2 + components/style/themes/default.less | 2 +- components/trigger/LazyRenderBox.vue | 2 +- components/trigger/Popup.vue | 28 ++- components/trigger/PopupInner.vue | 2 +- components/trigger/assets/index.less | 7 +- components/trigger/demo/nested.vue | 40 +++- components/trigger/demo/simple.vue | 279 +++++++++++++++++++++++++++ components/trigger/index.md | 160 +++++++++++++++ components/trigger/index.vue | 91 ++++----- 14 files changed, 560 insertions(+), 71 deletions(-) create mode 100644 components/trigger/demo/simple.vue create mode 100644 components/trigger/index.md diff --git a/components/_util/vnode.js b/components/_util/vnode.js index fa8756045..bde73fa43 100644 --- a/components/_util/vnode.js +++ b/components/_util/vnode.js @@ -1,12 +1,13 @@ +import clonedeep from 'lodash.clonedeep' export function cloneVNode (vnode, deep) { const cloned = new vnode.constructor( vnode.tag, - vnode.data, + clonedeep(vnode.data), vnode.children, vnode.text, vnode.elm, vnode.context, - vnode.componentOptions, + clonedeep(vnode.componentOptions), vnode.asyncFactory ) cloned.ns = vnode.ns @@ -30,7 +31,7 @@ export function cloneVNodes (vnodes, deep) { } export function cloneElement (node, nodeProps) { - const { props, key, ref } = nodeProps + const { props, key } = nodeProps if (node.componentOptions) { Object.assign(node.componentOptions.propsData, props) } @@ -40,7 +41,7 @@ export function cloneElement (node, nodeProps) { attrs = data.attrs, on = data.on, } = nodeProps - Object.assign(node.data, { style, attrs, class: cls, on }) + node.data = Object.assign(data, { style, attrs, class: cls, on }) if (key !== undefined) { node.key = key } diff --git a/components/_util/warning.js b/components/_util/warning.js index f7a301eb3..aa621accd 100644 --- a/components/_util/warning.js +++ b/components/_util/warning.js @@ -1,11 +1,14 @@ import warning from 'warning' const warned = {} -export default (valid, message) => { +export default (valid, message, throwError) => { if (process.env.NODE_ENV !== 'production') { if (!valid && !warned[message]) { warning(false, message) warned[message] = true + if (throwError) { + throw Error(message) + } } } } diff --git a/components/align/Align.vue b/components/align/Align.vue index a039d36a1..36f1d9e6a 100644 --- a/components/align/Align.vue +++ b/components/align/Align.vue @@ -1,5 +1,5 @@ + diff --git a/components/trigger/PopupInner.vue b/components/trigger/PopupInner.vue index 98bbfd08d..a7e0f9b3b 100644 --- a/components/trigger/PopupInner.vue +++ b/components/trigger/PopupInner.vue @@ -1,5 +1,5 @@ diff --git a/components/trigger/index.md b/components/trigger/index.md new file mode 100644 index 000000000..6887d36f5 --- /dev/null +++ b/components/trigger/index.md @@ -0,0 +1,160 @@ +## API + +### props + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
nametypedefaultdescription
popupClassNamestringadditional className added to popup
forceRenderbooleanfalsewhether render popup before first show
destroyPopupOnHidebooleanfalsewhether destroy popup when hide
getPopupClassNameFromAligngetPopupClassNameFromAlign(align: Object):Stringadditional className added to popup according to align
actionstring[]['hover']which actions cause popup shown. enum of 'hover','click','focus','contextMenu'
mouseEnterDelaynumber0delay time to show when mouse enter. unit: s.
mouseLeaveDelaynumber0.1delay time to hide when mouse leave. unit: s.
popupStyleObjectadditional style of popup
prefixClsStringrc-trigger-popupprefix class name
popupTransitionNameString|Objecthttps://github.com/react-component/animate
maskTransitionNameString|Objecthttps://github.com/react-component/animate
maskbooleanfalsewhether to support mask
maskClosablebooleantruewhether to support click mask to hide
popupVisiblebooleanwhether popup is visible
zIndexnumberpopup's zIndex
defaultPopupVisiblebooleanwhether popup is visible initially
popupAlignObject: alignConfig of [dom-align](https://github.com/yiminghe/dom-align)popup 's align config
getPopupContainergetPopupContainer(): HTMLElementfunction returning html node which will act as popup container
getDocumentgetDocument(): HTMLElementfunction returning document node which will be attached click event to close trigger
popupPlacementstringuse preset popup align config from builtinPlacements, can be merged by popupAlign prop
builtinPlacementsobjectbuiltin placement align map. used by placement prop
popupVisibleChange$emit(visible)call when popup visible is changed
popupAlign$emit(popupDomNode, align)callback when popup node is aligned
popupslot='popup'popup content
diff --git a/components/trigger/index.vue b/components/trigger/index.vue index 862d552e0..c95ce0634 100644 --- a/components/trigger/index.vue +++ b/components/trigger/index.vue @@ -2,11 +2,11 @@ import PropTypes from '../_util/vue-types' import contains from '../_util/Dom/contains' import addEventListener from '../_util/Dom/addEventListener' +import warning from '../_util/warning' import Popup from './Popup' import { getAlignFromPlacement, getPopupClassNameFromAlign } from './utils' -import getContainerRenderMixin from '../_util/getContainerRenderMixin' import StateMixin from '../_util/StateMixin' -import { cloneElement } from '../_util/vnode' +import { cloneElement, cloneVNode } from '../_util/vnode' function returnEmptyString () { return '' @@ -19,26 +19,6 @@ function returnDocument () { const ALL_HANDLERS = ['click', 'mousedown', 'touchStart', 'mouseenter', 'mouseleave', 'focus', 'blur', 'contextMenu'] -const mixins = [] - -mixins.push( - getContainerRenderMixin({ - autoMount: false, - - isVisible (instance) { - return instance.$data.sPopupVisible - }, - - isForceRender (instance) { - return instance.$props.forceRender - }, - - getContainer (instance) { - return instance.getContainer() - }, - }) -) - export default { name: 'Trigger', props: { @@ -65,7 +45,7 @@ export default { zIndex: PropTypes.number, focusDelay: PropTypes.number.def(0), blurDelay: PropTypes.number.def(0.15), - getPopupContainer: Function, + getPopupContainer: PropTypes.func, getDocument: PropTypes.func.def(returnDocument), forceRender: PropTypes.bool, destroyPopupOnHide: PropTypes.bool.def(false), @@ -74,15 +54,15 @@ export default { // onPopupAlign: PropTypes.func, popupAlign: PropTypes.object.def({}), popupVisible: PropTypes.bool, - // defaultPopupVisible: PropTypes.bool.def(false), - // maskTransitionName: PropTypes.oneOfType([ - // PropTypes.string, - // PropTypes.object, - // ]), - // maskAnimation: PropTypes.string, + defaultPopupVisible: PropTypes.bool.def(false), + maskTransitionName: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.object, + ]), + maskAnimation: PropTypes.string, }, - mixins: [StateMixin, ...mixins], + mixins: [StateMixin], data () { const props = this.$props let popupVisible @@ -184,9 +164,9 @@ export default { onPopupMouseleave (e) { if (e.relatedTarget && !e.relatedTarget.setTimeout && - this._component && - this._component.getPopupDomNode && - contains(this._component.getPopupDomNode(), e.relatedTarget)) { + this.$refs.popup && + this.$refs.popup.getPopupDomNode && + contains(this.$refs.popup.getPopupDomNode(), e.relatedTarget)) { return } this.delaySetPopupVisible(false, this.$props.mouseLeaveDelay) @@ -271,8 +251,8 @@ export default { }, getPopupDomNode () { // for test - if (this._component && this._component.getPopupDomNode) { - return this._component.getPopupDomNode() + if (this.$refs.popup && this.$refs.popup.getPopupDomNode) { + return this.$refs.popup.getPopupDomNode() } return null }, @@ -426,15 +406,17 @@ export default { createTwoChains (event) { const child = this.$slots.default[0] - let fn = () => {} - if (child && child.data && child.data.on) { - const childEvents = child.data.on - const events = (this.data ? this.data.on : {}) || {} - if (childEvents[event] && events[event]) { - return this[`fire${event}`] - } - fn = childEvents[event] || events[event] || fn + let fn = () => { + console.log('event', event) } + child.data = child.data || {} + child.data.on = child.data.on || {} + const childEvents = child.data.on + const events = (this.data ? this.data.on : {}) || {} + if (childEvents[event] && events[event]) { + return this[`fire${event}`] + } + fn = childEvents[event] || events[event] || fn return fn }, @@ -473,14 +455,15 @@ export default { return action.indexOf('focus') !== -1 || hideAction.indexOf('blur') !== -1 }, forcePopupAlign () { - if (this.$data.sPopupVisible && this._component && this._component.$refs.alignInstance) { - this._component.$refs.alignInstance.forceAlign() + if (this.$data.sPopupVisible && this.$refs.popup && this.$refs.popup.$refs.alignInstance) { + this.$refs.popup.$refs.alignInstance.forceAlign() } }, fireEvents (type, e) { const child = this.$slots.default[0] - if (child && child.data && child.on && child.on[type]) { - child.on[type](e) + if (child && child.data && child.data.on && child.data.on[type]) { + console.log(type, child.data.on[type]) + // child.data.on[type](e) } if (this.data && this.data.on && this.data.on[type]) { this.data.on[type](e) @@ -493,6 +476,9 @@ export default { }, render () { const children = this.$slots.default + if (children.length > 1) { + warning(false, 'Trigger $slots.default.length > 1, just support only one default', true) + } const child = children[0] const newChildProps = { props: {}, @@ -533,12 +519,17 @@ export default { newChildProps.on.blur = this.createTwoChains('blur') } - const trigger = cloneElement(child, newChildProps) - + const trigger = cloneElement(cloneVNode(child), newChildProps) + const { sPopupVisible, forceRender } = this + if (sPopupVisible || forceRender || this._component) { + this._component = this.getComponent() + } else { + this._component = null + } return ( {trigger} - {this.getComponent()} + {this._component} ) },