Drawer add draggable prop

This commit is contained in:
梁灏 2019-03-04 13:05:32 +08:00
parent 4616d882d5
commit a17511c397
3 changed files with 160 additions and 62 deletions

View file

@ -5,69 +5,68 @@
<Button @click="visible3 = true">show3</Button> <Button @click="visible3 = true">show3</Button>
<div style="width: 500px;height:500px;background: green;position: relative;"> <div style="width: 500px;height:500px;background: green;position: relative;">
<Drawer v-model="visible" placement="left" draggable inner :transfer="false" width="50" @on-resize-width="hrw" title="抽屉标题" :styles="styles" @on-close="handleClose">
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<Button @click="visible2 = true">show2</Button>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
</Drawer>
</div> </div>
<Drawer v-model="visible" width="70" inner title="抽屉标题" :styles="styles" @on-close="handleClose">
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<Button @click="visible2 = true">show2</Button>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
</Drawer>
<Drawer v-model="visible2" title="抽屉标题" placement="right"> <Drawer v-model="visible2" draggable title="抽屉标题" placement="right">
<p>一些内容</p> <p>一些内容</p>
<p>一些内容</p> <p>一些内容</p>
<p>一些内容</p> <p>一些内容</p>
@ -126,7 +125,7 @@
<p>一些内容</p> <p>一些内容</p>
<p>一些内容22</p> <p>一些内容22</p>
</Drawer> </Drawer>
<Drawer v-model="visible3" placement="left"> <Drawer v-model="visible3" draggable placement="left">
<p>一些内容</p> <p>一些内容</p>
<p>一些内容</p> <p>一些内容</p>
<p>一些内容</p> <p>一些内容</p>
@ -207,6 +206,9 @@
methods: { methods: {
handleClose () { handleClose () {
this.$Message.info('关闭了'); this.$Message.info('关闭了');
},
hrw (w) {
console.log(w);
} }
} }
}; };

View file

@ -15,6 +15,15 @@
<div :class="[prefixCls + '-header']" v-if="showHead"><slot name="header"><div :class="[prefixCls + '-header-inner']">{{ title }}</div></slot></div> <div :class="[prefixCls + '-header']" v-if="showHead"><slot name="header"><div :class="[prefixCls + '-header-inner']">{{ title }}</div></slot></div>
<div :class="[prefixCls + '-body']" :style="styles"><slot></slot></div> <div :class="[prefixCls + '-body']" :style="styles"><slot></slot></div>
</div> </div>
<div class="ivu-drawer-drag" :class="{ 'ivu-drawer-drag-left': placement === 'left' }" v-if="draggable" @mousedown="handleTriggerMousedown">
<slot name="trigger">
<div class="ivu-drawer-drag-move-trigger">
<div class="ivu-drawer-drag-move-trigger-point">
<i></i><i></i><i></i><i></i><i></i>
</div>
</div>
</slot>
</div>
</div> </div>
</transition> </transition>
</div> </div>
@ -27,6 +36,8 @@
import Emitter from '../../mixins/emitter'; import Emitter from '../../mixins/emitter';
import ScrollbarMixins from '../modal/mixins-scrollbar'; import ScrollbarMixins from '../modal/mixins-scrollbar';
import { on, off } from '../../utils/dom';
const prefixCls = 'ivu-drawer'; const prefixCls = 'ivu-drawer';
export default { export default {
@ -90,6 +101,11 @@
inner: { inner: {
type: Boolean, type: Boolean,
default: false default: false
},
// Whether drag and drop is allowed to adjust width
draggable: {
type: Boolean,
default: false
} }
}, },
data () { data () {
@ -98,6 +114,11 @@
visible: this.value, visible: this.value,
wrapShow: false, wrapShow: false,
showHead: true, showHead: true,
canMove: false,
dragWidth: this.width,
wrapperWidth: this.width,
wrapperLeft: 0,
minWidth: 256
}; };
}, },
computed: { computed: {
@ -108,14 +129,15 @@
[`${prefixCls}-hidden`]: !this.wrapShow, [`${prefixCls}-hidden`]: !this.wrapShow,
[`${this.className}`]: !!this.className, [`${this.className}`]: !!this.className,
[`${prefixCls}-no-mask`]: !this.mask, [`${prefixCls}-no-mask`]: !this.mask,
[`${prefixCls}-wrap-inner`]: this.inner [`${prefixCls}-wrap-inner`]: this.inner,
[`${prefixCls}-wrap-dragging`]: this.canMove
} }
]; ];
}, },
mainStyles () { mainStyles () {
let style = {}; let style = {};
const width = parseInt(this.width); const width = parseInt(this.dragWidth);
const styleWidth = { const styleWidth = {
width: width <= 100 ? `${width}%` : `${width}px` width: width <= 100 ? `${width}%` : `${width}px`
@ -168,6 +190,38 @@
const className = event.target.getAttribute('class'); const className = event.target.getAttribute('class');
if (className && className.indexOf(`${prefixCls}-wrap`) > -1) this.handleMask(); if (className && className.indexOf(`${prefixCls}-wrap`) > -1) this.handleMask();
}, },
handleMousemove (event) {
if (!this.canMove || !this.draggable) return;
// window0
this.handleSetWrapperWidth();
const left = event.pageX - this.wrapperLeft;
// left
let width = this.placement === 'right' ? this.wrapperWidth - left : left;
//
width = Math.max(width, parseFloat(this.minWidth));
event.atMin = width === parseFloat(this.minWidth);
// width100
if (width <= 100) width = (width / this.wrapperWidth) * 100;
this.dragWidth = width;
this.$emit('on-resize-width', parseInt(this.dragWidth));
},
handleSetWrapperWidth () {
const {
width,
left
} = this.$el.getBoundingClientRect();
this.wrapperWidth = width;
this.wrapperLeft = left;
},
handleMouseup () {
if (!this.draggable) return;
this.canMove = false;
},
handleTriggerMousedown () {
this.canMove = true;
// trigger
window.getSelection().removeAllRanges();
},
}, },
mounted () { mounted () {
if (this.visible) { if (this.visible) {
@ -181,8 +235,14 @@
} }
this.showHead = showHead; this.showHead = showHead;
on(document, 'mousemove', this.handleMousemove);
on(document, 'mouseup', this.handleMouseup);
this.handleSetWrapperWidth();
}, },
beforeDestroy () { beforeDestroy () {
off(document, 'mousemove', this.handleMousemove);
off(document, 'mouseup', this.handleMouseup);
this.removeScrollEffect(); this.removeScrollEffect();
}, },
watch: { watch: {

View file

@ -36,6 +36,10 @@
position: absolute; position: absolute;
overflow: hidden; overflow: hidden;
} }
&-dragging{
user-select: none;
}
} }
&-wrap * { &-wrap * {
@ -93,4 +97,36 @@
&-no-mask{ &-no-mask{
pointer-events: none; pointer-events: none;
} }
&-drag{
top: 0;
height: 100%;
width: 0;
position: absolute;
&-left{
right: 0;
}
&-move-trigger{
width: 8px;
height: 100px;
line-height: 100px;
position: absolute;
top: 50%;
background: rgb(243, 243, 243);
transform: translate(-50%, -50%);
border-radius: ~"4px / 6px";
box-shadow: 0 0 1px 1px rgba(0, 0, 0, .2);
cursor: col-resize;
&-point{
display: inline-block;
width: 50%;
transform: translateX(50%);
i{
display: block;
border-bottom: 1px solid rgb(192, 192, 192);
padding-bottom: 2px;
}
}
}
}
} }