Modal add dragable prop

This commit is contained in:
梁灏 2018-06-26 20:51:59 +08:00
parent 1c7289e9dd
commit d4b59a9adb
3 changed files with 94 additions and 6 deletions

View file

@ -5,7 +5,7 @@
<Modal <Modal
v-model="modal1" v-model="modal1"
title="Common Modal dialog box title" title="Common Modal dialog box title"
:mask="false" dragable
@on-ok="ok" @on-ok="ok"
@on-cancel="cancel"> @on-cancel="cancel">
<p>Content of dialog</p> <p>Content of dialog</p>

View file

@ -6,13 +6,16 @@
<div :class="wrapClasses" @click="handleWrapClick"> <div :class="wrapClasses" @click="handleWrapClick">
<transition :name="transitionNames[0]" @after-leave="animationFinish"> <transition :name="transitionNames[0]" @after-leave="animationFinish">
<div :class="classes" :style="mainStyles" v-show="visible"> <div :class="classes" :style="mainStyles" v-show="visible">
<div :class="contentClasses"> <div :class="contentClasses" ref="content" :style="contentStyles">
<a :class="[prefixCls + '-close']" v-if="closable" @click="close"> <a :class="[prefixCls + '-close']" v-if="closable" @click="close">
<slot name="close"> <slot name="close">
<Icon type="ios-close"></Icon> <Icon type="ios-close"></Icon>
</slot> </slot>
</a> </a>
<div :class="[prefixCls + '-header']" v-if="showHead"><slot name="header"><div :class="[prefixCls + '-header-inner']">{{ title }}</div></slot></div> <div :class="[prefixCls + '-header']"
@mousedown="handleMoveStart"
v-if="showHead"
><slot name="header"><div :class="[prefixCls + '-header-inner']">{{ title }}</div></slot></div>
<div :class="[prefixCls + '-body']"><slot></slot></div> <div :class="[prefixCls + '-body']"><slot></slot></div>
<div :class="[prefixCls + '-footer']" v-if="!footerHide"> <div :class="[prefixCls + '-footer']" v-if="!footerHide">
<slot name="footer"> <slot name="footer">
@ -34,6 +37,8 @@
import Emitter from '../../mixins/emitter'; import Emitter from '../../mixins/emitter';
import ScrollbarMixins from './mixins-scrollbar'; import ScrollbarMixins from './mixins-scrollbar';
import { on, off } from '../../utils/dom';
const prefixCls = 'ivu-modal'; const prefixCls = 'ivu-modal';
export default { export default {
@ -115,7 +120,14 @@
wrapShow: false, wrapShow: false,
showHead: true, showHead: true,
buttonLoading: false, buttonLoading: false,
visible: this.value visible: this.value,
dragData: {
x: null,
y: null,
dragX: null,
dragY: null,
dragging: false
}
}; };
}, },
computed: { computed: {
@ -146,7 +158,9 @@
return [ return [
`${prefixCls}-content`, `${prefixCls}-content`,
{ {
[`${prefixCls}-content-no-mask`]: !this.showMask [`${prefixCls}-content-no-mask`]: !this.showMask,
[`${prefixCls}-content-drag`]: this.dragable,
[`${prefixCls}-content-dragging`]: this.dragable && this.dragData.dragging
} }
]; ];
}, },
@ -154,7 +168,9 @@
let style = {}; let style = {};
const width = parseInt(this.width); const width = parseInt(this.width);
const styleWidth = { const styleWidth = this.dragData.x !== null ? {
top: 0
} : {
width: width <= 100 ? `${width}%` : `${width}px` width: width <= 100 ? `${width}%` : `${width}px`
}; };
@ -164,6 +180,22 @@
return style; return style;
}, },
contentStyles () {
let style = {};
if (this.dragable) {
if (this.dragData.x !== null) style.left = `${this.dragData.x}px`;
if (this.dragData.y !== null) style.top = `${this.dragData.y}px`;
const width = parseInt(this.width);
const styleWidth = {
width: width <= 100 ? `${width}%` : `${width}px`
};
Object.assign(style, styleWidth);
}
return style;
},
localeOkText () { localeOkText () {
if (this.okText === undefined) { if (this.okText === undefined) {
return this.t('i.modal.okText'); return this.t('i.modal.okText');
@ -219,6 +251,51 @@
}, },
animationFinish() { animationFinish() {
this.$emit('on-hidden'); this.$emit('on-hidden');
},
handleMoveStart (event) {
if (!this.dragable) return false;
const $content = this.$refs.content;
const rect = $content.getBoundingClientRect();
this.dragData.x = rect.x;
this.dragData.y = rect.y;
const distance = {
x: event.clientX,
y: event.clientY
};
this.dragData.dragX = distance.x;
this.dragData.dragY = distance.y;
this.dragData.dragging = true;
on(window, 'mousemove', this.handleMoveMove);
on(window, 'mouseup', this.handleMoveEnd);
},
handleMoveMove (event) {
if (!this.dragData.dragging) return false;
const distance = {
x: event.clientX,
y: event.clientY
};
const diff_distance = {
x: distance.x - this.dragData.dragX,
y: distance.y - this.dragData.dragY
};
this.dragData.x += diff_distance.x;
this.dragData.y += diff_distance.y;
this.dragData.dragX = distance.x;
this.dragData.dragY = distance.y;
},
handleMoveEnd (event) {
this.dragData.dragging = false;
off(window, 'mousemove', this.handleMoveMove);
off(window, 'mouseup', this.handleMoveEnd);
} }
}, },
mounted () { mounted () {

View file

@ -44,6 +44,17 @@
&-no-mask{ &-no-mask{
pointer-events: auto; pointer-events: auto;
} }
&-drag{
position: absolute;
.@{modal-prefix-cls}-header{
cursor: move;
}
}
&-dragging{
-webkit-user-select: none;
-moz-user-select: none;
user-select: none;
}
} }
&-header { &-header {