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
v-model="modal1"
title="Common Modal dialog box title"
:mask="false"
dragable
@on-ok="ok"
@on-cancel="cancel">
<p>Content of dialog</p>

View file

@ -6,13 +6,16 @@
<div :class="wrapClasses" @click="handleWrapClick">
<transition :name="transitionNames[0]" @after-leave="animationFinish">
<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">
<slot name="close">
<Icon type="ios-close"></Icon>
</slot>
</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 + '-footer']" v-if="!footerHide">
<slot name="footer">
@ -34,6 +37,8 @@
import Emitter from '../../mixins/emitter';
import ScrollbarMixins from './mixins-scrollbar';
import { on, off } from '../../utils/dom';
const prefixCls = 'ivu-modal';
export default {
@ -115,7 +120,14 @@
wrapShow: false,
showHead: true,
buttonLoading: false,
visible: this.value
visible: this.value,
dragData: {
x: null,
y: null,
dragX: null,
dragY: null,
dragging: false
}
};
},
computed: {
@ -146,7 +158,9 @@
return [
`${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 = {};
const width = parseInt(this.width);
const styleWidth = {
const styleWidth = this.dragData.x !== null ? {
top: 0
} : {
width: width <= 100 ? `${width}%` : `${width}px`
};
@ -164,6 +180,22 @@
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 () {
if (this.okText === undefined) {
return this.t('i.modal.okText');
@ -219,6 +251,51 @@
},
animationFinish() {
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 () {

View file

@ -44,6 +44,17 @@
&-no-mask{
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 {