iview/src/components/split/split.vue

164 lines
6.5 KiB
Vue
Raw Normal View History

2018-06-07 15:34:42 +08:00
<template>
2018-06-30 16:06:25 +08:00
<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>
2018-06-07 15:34:42 +08:00
</div>
</template>
<script>
2018-06-30 16:06:25 +08:00
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
2018-06-21 09:15:00 +08:00
},
2018-06-30 16:06:25 +08:00
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');
}
2018-06-21 09:15:00 +08:00
},
2018-06-30 16:06:25 +08:00
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;
});
2018-06-21 09:15:00 +08:00
}
2018-06-30 16:06:25 +08:00
};
2018-06-07 15:34:42 +08:00
</script>