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>
<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>
<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>
@ -126,7 +125,7 @@
<p>一些内容</p>
<p>一些内容22</p>
</Drawer>
<Drawer v-model="visible3" placement="left">
<Drawer v-model="visible3" draggable placement="left">
<p>一些内容</p>
<p>一些内容</p>
<p>一些内容</p>
@ -207,6 +206,9 @@
methods: {
handleClose () {
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 + '-body']" :style="styles"><slot></slot></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>
</transition>
</div>
@ -27,6 +36,8 @@
import Emitter from '../../mixins/emitter';
import ScrollbarMixins from '../modal/mixins-scrollbar';
import { on, off } from '../../utils/dom';
const prefixCls = 'ivu-drawer';
export default {
@ -90,6 +101,11 @@
inner: {
type: Boolean,
default: false
},
// Whether drag and drop is allowed to adjust width
draggable: {
type: Boolean,
default: false
}
},
data () {
@ -98,6 +114,11 @@
visible: this.value,
wrapShow: false,
showHead: true,
canMove: false,
dragWidth: this.width,
wrapperWidth: this.width,
wrapperLeft: 0,
minWidth: 256
};
},
computed: {
@ -108,14 +129,15 @@
[`${prefixCls}-hidden`]: !this.wrapShow,
[`${this.className}`]: !!this.className,
[`${prefixCls}-no-mask`]: !this.mask,
[`${prefixCls}-wrap-inner`]: this.inner
[`${prefixCls}-wrap-inner`]: this.inner,
[`${prefixCls}-wrap-dragging`]: this.canMove
}
];
},
mainStyles () {
let style = {};
const width = parseInt(this.width);
const width = parseInt(this.dragWidth);
const styleWidth = {
width: width <= 100 ? `${width}%` : `${width}px`
@ -168,6 +190,38 @@
const className = event.target.getAttribute('class');
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 () {
if (this.visible) {
@ -181,8 +235,14 @@
}
this.showHead = showHead;
on(document, 'mousemove', this.handleMousemove);
on(document, 'mouseup', this.handleMouseup);
this.handleSetWrapperWidth();
},
beforeDestroy () {
off(document, 'mousemove', this.handleMousemove);
off(document, 'mouseup', this.handleMouseup);
this.removeScrollEffect();
},
watch: {

View file

@ -36,6 +36,10 @@
position: absolute;
overflow: hidden;
}
&-dragging{
user-select: none;
}
}
&-wrap * {
@ -93,4 +97,36 @@
&-no-mask{
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;
}
}
}
}
}