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
+
+
+
+
+ name |
+ type |
+ default |
+ description |
+
+
+
+
+ popupClassName |
+ string |
+ |
+ additional className added to popup |
+
+
+ forceRender |
+ boolean |
+ false |
+ whether render popup before first show |
+
+
+ destroyPopupOnHide |
+ boolean |
+ false |
+ whether destroy popup when hide |
+
+
+ getPopupClassNameFromAlign |
+ getPopupClassNameFromAlign(align: Object):String |
+ |
+ additional className added to popup according to align |
+
+
+ action |
+ string[] |
+ ['hover'] |
+ which actions cause popup shown. enum of 'hover','click','focus','contextMenu' |
+
+
+ mouseEnterDelay |
+ number |
+ 0 |
+ delay time to show when mouse enter. unit: s. |
+
+
+ mouseLeaveDelay |
+ number |
+ 0.1 |
+ delay time to hide when mouse leave. unit: s. |
+
+
+ popupStyle |
+ Object |
+ |
+ additional style of popup |
+
+
+ prefixCls |
+ String |
+ rc-trigger-popup |
+ prefix class name |
+
+
+ popupTransitionName |
+ String|Object |
+ |
+ https://github.com/react-component/animate |
+
+
+ maskTransitionName |
+ String|Object |
+ |
+ https://github.com/react-component/animate |
+
+
+ mask |
+ boolean |
+ false |
+ whether to support mask |
+
+
+ maskClosable |
+ boolean |
+ true |
+ whether to support click mask to hide |
+
+
+ popupVisible |
+ boolean |
+ |
+ whether popup is visible |
+
+
+ zIndex |
+ number |
+ |
+ popup's zIndex |
+
+
+ defaultPopupVisible |
+ boolean |
+ |
+ whether popup is visible initially |
+
+
+ popupAlign |
+ Object: alignConfig of [dom-align](https://github.com/yiminghe/dom-align) |
+ |
+ popup 's align config |
+
+
+ getPopupContainer |
+ getPopupContainer(): HTMLElement |
+ |
+ function returning html node which will act as popup container |
+
+
+ getDocument |
+ getDocument(): HTMLElement |
+ |
+ function returning document node which will be attached click event to close trigger |
+
+
+ popupPlacement |
+ string |
+ |
+ use preset popup align config from builtinPlacements, can be merged by popupAlign prop |
+
+
+ builtinPlacements |
+ object |
+ |
+ builtin 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 |
+
+
+ popup |
+ slot='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}
)
},