iview/src/components/split/split.vue
2018-06-30 16:06:25 +08:00

163 lines
6.5 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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 {
name: 'Split',
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>