tangjinzhou
7 years ago
7 changed files with 207 additions and 2 deletions
@ -0,0 +1,5 @@
|
||||
import addDOMEventListener from 'add-dom-event-listener' |
||||
|
||||
export default function addEventListenerWrap (target, eventType, cb) { |
||||
return addDOMEventListener(target, eventType, cb) |
||||
} |
@ -0,0 +1,7 @@
|
||||
export default (node, props) => { |
||||
if (node.componentOptions) { |
||||
const propsData = node.componentOptions.propsData |
||||
Object.assign(propsData, props) |
||||
} |
||||
return node |
||||
} |
@ -0,0 +1,104 @@
|
||||
<script> |
||||
import PropTypes from 'vue-types' |
||||
import align from 'dom-align' |
||||
import addEventListener from '../_util/Dom/addEventListener' |
||||
import cloneElement from '../_util/cloneElement' |
||||
function noop () { |
||||
} |
||||
|
||||
function buffer (fn, ms) { |
||||
let timer |
||||
|
||||
function clear () { |
||||
if (timer) { |
||||
clearTimeout(timer) |
||||
timer = null |
||||
} |
||||
} |
||||
|
||||
function bufferFn () { |
||||
clear() |
||||
timer = setTimeout(fn, ms) |
||||
} |
||||
|
||||
bufferFn.clear = clear |
||||
|
||||
return bufferFn |
||||
} |
||||
|
||||
export default { |
||||
props: { |
||||
childrenProps: PropTypes.object, |
||||
align: PropTypes.object.isRequired, |
||||
target: PropTypes.func.def(noop), |
||||
monitorBufferTime: PropTypes.number.def(50), |
||||
monitorWindowResize: PropTypes.bool.def(false), |
||||
disabled: PropTypes.bool.def(false), |
||||
}, |
||||
|
||||
mounted () { |
||||
const props = this.$props |
||||
// if parent ref not attached .... use document.getElementById |
||||
this.forceAlign() |
||||
if (!props.disabled && props.monitorWindowResize) { |
||||
this.startMonitorWindowResize() |
||||
} |
||||
}, |
||||
|
||||
updated () { |
||||
const props = this.$props |
||||
|
||||
this.forceAlign() |
||||
|
||||
if (props.monitorWindowResize && !props.disabled) { |
||||
this.startMonitorWindowResize() |
||||
} else { |
||||
this.stopMonitorWindowResize() |
||||
} |
||||
}, |
||||
|
||||
beforeDestory () { |
||||
this.stopMonitorWindowResize() |
||||
}, |
||||
methods: { |
||||
startMonitorWindowResize () { |
||||
if (!this.resizeHandler) { |
||||
this.bufferMonitor = buffer(this.forceAlign, this.$props.monitorBufferTime) |
||||
this.resizeHandler = addEventListener(window, 'resize', this.bufferMonitor) |
||||
} |
||||
}, |
||||
|
||||
stopMonitorWindowResize () { |
||||
if (this.resizeHandler) { |
||||
this.bufferMonitor.clear() |
||||
this.resizeHandler.remove() |
||||
this.resizeHandler = null |
||||
} |
||||
}, |
||||
|
||||
forceAlign () { |
||||
const props = this.$props |
||||
if (!props.disabled) { |
||||
const source = this.$el |
||||
this.$emit('align', source, align(source, props.target(), props.align)) |
||||
} |
||||
}, |
||||
}, |
||||
|
||||
render () { |
||||
const { childrenProps } = this.$props |
||||
const child = this.$slots.default[0] |
||||
if (childrenProps) { |
||||
const newProps = {} |
||||
for (const prop in childrenProps) { |
||||
if (childrenProps.hasOwnProperty(prop)) { |
||||
newProps[prop] = this.props[childrenProps[prop]] |
||||
} |
||||
} |
||||
return cloneElement(child, newProps) |
||||
} |
||||
return child |
||||
}, |
||||
} |
||||
|
||||
</script> |
@ -0,0 +1,81 @@
|
||||
<script> |
||||
import Align from '../index' |
||||
import StateMixin from '../../_util/StateMixin' |
||||
|
||||
export default { |
||||
mixins: [StateMixin], |
||||
data () { |
||||
return { |
||||
monitor: true, |
||||
align: { |
||||
points: ['tl', 'tc'], |
||||
}, |
||||
} |
||||
}, |
||||
methods: { |
||||
getTarget () { |
||||
const ref = this.$refs.container |
||||
// if (!ref) { |
||||
// // parent ref not attached |
||||
// ref = document.getElementById('container') |
||||
// } |
||||
return ref |
||||
}, |
||||
|
||||
toggleMonitor () { |
||||
this.setState({ |
||||
monitor: !this.$data.monitor, |
||||
}) |
||||
}, |
||||
|
||||
forceAlign () { |
||||
this.setState({ |
||||
align: Object.assign({}, this.$data.align), |
||||
}) |
||||
}, |
||||
}, |
||||
|
||||
render () { |
||||
return ( |
||||
<div |
||||
style={{ |
||||
margin: 50, |
||||
}} |
||||
> |
||||
<p> |
||||
<button onClick={this.forceAlign}>force align</button> |
||||
|
||||
<button onClick={this.toggleMonitor}>toggle monitor</button> |
||||
</p> |
||||
<div |
||||
ref='container' |
||||
id='container' |
||||
style={{ |
||||
width: '80%', |
||||
height: '500px', |
||||
border: '1px solid red', |
||||
}} |
||||
> |
||||
<Align |
||||
target={this.getTarget} |
||||
monitorWindowResize={this.$data.monitor} |
||||
align={this.$data.align} |
||||
> |
||||
<div |
||||
style={{ |
||||
position: 'absolute', |
||||
width: '50px', |
||||
height: '50px', |
||||
background: 'yellow', |
||||
}} |
||||
> |
||||
source |
||||
</div> |
||||
</Align> |
||||
</div> |
||||
</div> |
||||
) |
||||
}, |
||||
} |
||||
|
||||
</script> |
@ -0,0 +1,3 @@
|
||||
// export this package's api
|
||||
import Align from './Align' |
||||
export default Align |
Loading…
Reference in new issue