2018-06-07 15:34:42 +08:00
|
|
|
|
<template>
|
|
|
|
|
<div ref="outerWrapper" :class="wrapperClasses">
|
|
|
|
|
<div v-if="isHorizontal" :class="`${prefix}-horizontal`">
|
|
|
|
|
<div :style="{right: `${anotherOffset}%`}" :class="[`${prefix}-pane`, 'left-pane']"><slot name="left"/></div>
|
|
|
|
|
<div :class="`${prefix}-trigger-con`" :style="{left: `${offset}%`}" @mousedown="handleMousedown">
|
|
|
|
|
<slot name="trigger">
|
|
|
|
|
<trigger mode="vertical"/>
|
|
|
|
|
</slot>
|
|
|
|
|
</div>
|
|
|
|
|
<div :style="{left: `${offset}%`}" :class="[`${prefix}-pane`, 'right-pane']"><slot name="right"/></div>
|
|
|
|
|
</div>
|
|
|
|
|
<div v-else :class="`${prefix}-vertical`">
|
|
|
|
|
<div :style="{bottom: `${anotherOffset}%`}" :class="[`${prefix}-pane`, 'top-pane']"><slot name="top"/></div>
|
|
|
|
|
<div :class="`${prefix}-trigger-con`" :style="{top: `${offset}%`}" @mousedown="handleMousedown">
|
|
|
|
|
<slot name="trigger">
|
|
|
|
|
<trigger mode="horizontal"/>
|
|
|
|
|
</slot>
|
|
|
|
|
</div>
|
|
|
|
|
<div :style="{top: `${offset}%`}" :class="[`${prefix}-pane`, 'bottom-pane']"><slot name="bottom"/></div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import { oneOf } from '../../utils/assist';
|
|
|
|
|
import { on, off } from '../../utils/dom';
|
|
|
|
|
import Trigger from './trigger.vue'
|
|
|
|
|
export default {
|
2018-06-20 15:23:23 +08:00
|
|
|
|
name: 'Split',
|
2018-06-07 15:34:42 +08:00
|
|
|
|
components: {
|
|
|
|
|
Trigger
|
|
|
|
|
},
|
|
|
|
|
props: {
|
|
|
|
|
value: {
|
|
|
|
|
type: [Number, String],
|
|
|
|
|
default: 0.5
|
|
|
|
|
},
|
|
|
|
|
mode: {
|
|
|
|
|
validator (value) {
|
|
|
|
|
return oneOf(value, ['horizontal', 'vertical'])
|
|
|
|
|
},
|
|
|
|
|
default: 'horizontal'
|
|
|
|
|
},
|
|
|
|
|
min: {
|
|
|
|
|
type: [Number, String],
|
|
|
|
|
default: '40px'
|
|
|
|
|
},
|
|
|
|
|
max: {
|
|
|
|
|
type: [Number, String],
|
|
|
|
|
default: '40px'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
/**
|
|
|
|
|
* Events
|
|
|
|
|
* @on-move-start
|
|
|
|
|
* @on-moving 返回值:事件对象,但是在事件对象中加入了两个参数:atMin(当前是否在最小值处), atMax(当前是否在最大值处)
|
|
|
|
|
* @on-move-end
|
|
|
|
|
*/
|
|
|
|
|
data () {
|
|
|
|
|
return {
|
|
|
|
|
prefix: 'ivu-split',
|
|
|
|
|
offset: 0,
|
|
|
|
|
oldOffset: 0,
|
|
|
|
|
isMoving: false
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
computed: {
|
|
|
|
|
wrapperClasses () {
|
|
|
|
|
return [
|
|
|
|
|
`${this.prefix}-wrapper`,
|
|
|
|
|
this.isMoving ? 'no-select' : ''
|
|
|
|
|
]
|
|
|
|
|
},
|
|
|
|
|
isHorizontal () {
|
|
|
|
|
return this.mode === 'horizontal'
|
|
|
|
|
},
|
|
|
|
|
anotherOffset () {
|
|
|
|
|
return 100 - this.offset
|
|
|
|
|
},
|
|
|
|
|
valueIsPx () {
|
|
|
|
|
return typeof this.value === 'string'
|
|
|
|
|
},
|
|
|
|
|
offsetSize () {
|
|
|
|
|
return this.isHorizontal ? 'offsetWidth' : 'offsetHeight'
|
|
|
|
|
},
|
|
|
|
|
computedMin () {
|
|
|
|
|
return this.getComputedThresholdValue('min')
|
|
|
|
|
},
|
|
|
|
|
computedMax () {
|
|
|
|
|
return this.getComputedThresholdValue('max')
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
px2percent (numerator, denominator) {
|
|
|
|
|
return parseFloat(numerator) / parseFloat(denominator)
|
|
|
|
|
},
|
|
|
|
|
getComputedThresholdValue (type) {
|
|
|
|
|
let size = this.$refs.outerWrapper[this.offsetSize]
|
|
|
|
|
if (this.valueIsPx) return typeof this[type] === 'string' ? this[type] : size * this[type]
|
|
|
|
|
else return typeof this[type] === 'string' ? this.px2percent(this[type], size) : this[type]
|
|
|
|
|
},
|
|
|
|
|
getMin (value1, value2) {
|
|
|
|
|
if (this.valueIsPx) return `${Math.min(parseFloat(value1), parseFloat(value2))}px`
|
|
|
|
|
else return Math.min(value1, value2)
|
|
|
|
|
},
|
|
|
|
|
getMax (value1, value2) {
|
|
|
|
|
if (this.valueIsPx) return `${Math.max(parseFloat(value1), parseFloat(value2))}px`
|
|
|
|
|
else return Math.max(value1, value2)
|
|
|
|
|
},
|
|
|
|
|
getAnotherOffset (value) {
|
|
|
|
|
let res = 0
|
|
|
|
|
if (this.valueIsPx) res = `${this.$refs.outerWrapper[this.offsetSize] - parseFloat(value)}px`
|
|
|
|
|
else res = 1 - value
|
|
|
|
|
return res
|
|
|
|
|
},
|
|
|
|
|
handleMove (e) {
|
|
|
|
|
let pageOffset = this.isHorizontal ? e.pageX : e.pageY
|
|
|
|
|
let offset = pageOffset - this.initOffset
|
|
|
|
|
let outerWidth = this.$refs.outerWrapper[this.offsetSize]
|
|
|
|
|
let value = this.valueIsPx ? `${parseFloat(this.oldOffset) + offset}px` : (this.px2percent(outerWidth * this.oldOffset + offset, outerWidth))
|
|
|
|
|
let anotherValue = this.getAnotherOffset(value)
|
|
|
|
|
if (parseFloat(value) <= parseFloat(this.computedMin)) value = this.getMax(value, this.computedMin)
|
|
|
|
|
if (parseFloat(anotherValue) <= parseFloat(this.computedMax)) value = this.getAnotherOffset(this.getMax(anotherValue, this.computedMax))
|
|
|
|
|
e.atMin = this.value === this.computedMin
|
|
|
|
|
e.atMax = this.valueIsPx ? this.getAnotherOffset(this.value) === this.computedMax : this.getAnotherOffset(this.value).toFixed(5) === this.computedMax.toFixed(5)
|
|
|
|
|
this.$emit('input', value)
|
|
|
|
|
this.$emit('on-moving', e)
|
|
|
|
|
},
|
|
|
|
|
handleUp () {
|
|
|
|
|
this.isMoving = false
|
|
|
|
|
off(document, 'mousemove', this.handleMove)
|
|
|
|
|
off(document, 'mouseup', this.handleUp)
|
|
|
|
|
this.$emit('on-move-end')
|
|
|
|
|
},
|
|
|
|
|
handleMousedown (e) {
|
|
|
|
|
this.initOffset = this.isHorizontal ? e.pageX : e.pageY
|
|
|
|
|
this.oldOffset = this.value
|
|
|
|
|
this.isMoving = true
|
|
|
|
|
on(document, 'mousemove', this.handleMove)
|
|
|
|
|
on(document, 'mouseup', this.handleUp)
|
|
|
|
|
this.$emit('on-move-start')
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
watch: {
|
|
|
|
|
value () {
|
|
|
|
|
this.offset = (this.valueIsPx ? this.px2percent(this.value, this.$refs.outerWrapper[this.offsetSize]) : this.value) * 10000 / 100
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
mounted () {
|
|
|
|
|
this.$nextTick(() => {
|
|
|
|
|
this.offset = (this.valueIsPx ? this.px2percent(this.value, this.$refs.outerWrapper[this.offsetSize]) : this.value) * 10000 / 100
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|