Commit d4b59a9adbeacacf4ed8c4e2d55f3954227bc4da

Authored by 梁灏
1 parent 1c7289e9

Modal add dragable prop

examples/routers/modal.vue
@@ -5,7 +5,7 @@ @@ -5,7 +5,7 @@
5 <Modal 5 <Modal
6 v-model="modal1" 6 v-model="modal1"
7 title="Common Modal dialog box title" 7 title="Common Modal dialog box title"
8 - :mask="false" 8 + dragable
9 @on-ok="ok" 9 @on-ok="ok"
10 @on-cancel="cancel"> 10 @on-cancel="cancel">
11 <p>Content of dialog</p> 11 <p>Content of dialog</p>
src/components/modal/modal.vue
@@ -6,13 +6,16 @@ @@ -6,13 +6,16 @@
6 <div :class="wrapClasses" @click="handleWrapClick"> 6 <div :class="wrapClasses" @click="handleWrapClick">
7 <transition :name="transitionNames[0]" @after-leave="animationFinish"> 7 <transition :name="transitionNames[0]" @after-leave="animationFinish">
8 <div :class="classes" :style="mainStyles" v-show="visible"> 8 <div :class="classes" :style="mainStyles" v-show="visible">
9 - <div :class="contentClasses"> 9 + <div :class="contentClasses" ref="content" :style="contentStyles">
10 <a :class="[prefixCls + '-close']" v-if="closable" @click="close"> 10 <a :class="[prefixCls + '-close']" v-if="closable" @click="close">
11 <slot name="close"> 11 <slot name="close">
12 <Icon type="ios-close"></Icon> 12 <Icon type="ios-close"></Icon>
13 </slot> 13 </slot>
14 </a> 14 </a>
15 - <div :class="[prefixCls + '-header']" v-if="showHead"><slot name="header"><div :class="[prefixCls + '-header-inner']">{{ title }}</div></slot></div> 15 + <div :class="[prefixCls + '-header']"
  16 + @mousedown="handleMoveStart"
  17 + v-if="showHead"
  18 + ><slot name="header"><div :class="[prefixCls + '-header-inner']">{{ title }}</div></slot></div>
16 <div :class="[prefixCls + '-body']"><slot></slot></div> 19 <div :class="[prefixCls + '-body']"><slot></slot></div>
17 <div :class="[prefixCls + '-footer']" v-if="!footerHide"> 20 <div :class="[prefixCls + '-footer']" v-if="!footerHide">
18 <slot name="footer"> 21 <slot name="footer">
@@ -34,6 +37,8 @@ @@ -34,6 +37,8 @@
34 import Emitter from '../../mixins/emitter'; 37 import Emitter from '../../mixins/emitter';
35 import ScrollbarMixins from './mixins-scrollbar'; 38 import ScrollbarMixins from './mixins-scrollbar';
36 39
  40 + import { on, off } from '../../utils/dom';
  41 +
37 const prefixCls = 'ivu-modal'; 42 const prefixCls = 'ivu-modal';
38 43
39 export default { 44 export default {
@@ -115,7 +120,14 @@ @@ -115,7 +120,14 @@
115 wrapShow: false, 120 wrapShow: false,
116 showHead: true, 121 showHead: true,
117 buttonLoading: false, 122 buttonLoading: false,
118 - visible: this.value 123 + visible: this.value,
  124 + dragData: {
  125 + x: null,
  126 + y: null,
  127 + dragX: null,
  128 + dragY: null,
  129 + dragging: false
  130 + }
119 }; 131 };
120 }, 132 },
121 computed: { 133 computed: {
@@ -146,7 +158,9 @@ @@ -146,7 +158,9 @@
146 return [ 158 return [
147 `${prefixCls}-content`, 159 `${prefixCls}-content`,
148 { 160 {
149 - [`${prefixCls}-content-no-mask`]: !this.showMask 161 + [`${prefixCls}-content-no-mask`]: !this.showMask,
  162 + [`${prefixCls}-content-drag`]: this.dragable,
  163 + [`${prefixCls}-content-dragging`]: this.dragable && this.dragData.dragging
150 } 164 }
151 ]; 165 ];
152 }, 166 },
@@ -154,7 +168,9 @@ @@ -154,7 +168,9 @@
154 let style = {}; 168 let style = {};
155 169
156 const width = parseInt(this.width); 170 const width = parseInt(this.width);
157 - const styleWidth = { 171 + const styleWidth = this.dragData.x !== null ? {
  172 + top: 0
  173 + } : {
158 width: width <= 100 ? `${width}%` : `${width}px` 174 width: width <= 100 ? `${width}%` : `${width}px`
159 }; 175 };
160 176
@@ -164,6 +180,22 @@ @@ -164,6 +180,22 @@
164 180
165 return style; 181 return style;
166 }, 182 },
  183 + contentStyles () {
  184 + let style = {};
  185 +
  186 + if (this.dragable) {
  187 + if (this.dragData.x !== null) style.left = `${this.dragData.x}px`;
  188 + if (this.dragData.y !== null) style.top = `${this.dragData.y}px`;
  189 + const width = parseInt(this.width);
  190 + const styleWidth = {
  191 + width: width <= 100 ? `${width}%` : `${width}px`
  192 + };
  193 +
  194 + Object.assign(style, styleWidth);
  195 + }
  196 +
  197 + return style;
  198 + },
167 localeOkText () { 199 localeOkText () {
168 if (this.okText === undefined) { 200 if (this.okText === undefined) {
169 return this.t('i.modal.okText'); 201 return this.t('i.modal.okText');
@@ -219,6 +251,51 @@ @@ -219,6 +251,51 @@
219 }, 251 },
220 animationFinish() { 252 animationFinish() {
221 this.$emit('on-hidden'); 253 this.$emit('on-hidden');
  254 + },
  255 + handleMoveStart (event) {
  256 + if (!this.dragable) return false;
  257 +
  258 + const $content = this.$refs.content;
  259 + const rect = $content.getBoundingClientRect();
  260 + this.dragData.x = rect.x;
  261 + this.dragData.y = rect.y;
  262 +
  263 + const distance = {
  264 + x: event.clientX,
  265 + y: event.clientY
  266 + };
  267 +
  268 + this.dragData.dragX = distance.x;
  269 + this.dragData.dragY = distance.y;
  270 +
  271 + this.dragData.dragging = true;
  272 +
  273 + on(window, 'mousemove', this.handleMoveMove);
  274 + on(window, 'mouseup', this.handleMoveEnd);
  275 + },
  276 + handleMoveMove (event) {
  277 + if (!this.dragData.dragging) return false;
  278 +
  279 + const distance = {
  280 + x: event.clientX,
  281 + y: event.clientY
  282 + };
  283 +
  284 + const diff_distance = {
  285 + x: distance.x - this.dragData.dragX,
  286 + y: distance.y - this.dragData.dragY
  287 + };
  288 +
  289 + this.dragData.x += diff_distance.x;
  290 + this.dragData.y += diff_distance.y;
  291 +
  292 + this.dragData.dragX = distance.x;
  293 + this.dragData.dragY = distance.y;
  294 + },
  295 + handleMoveEnd (event) {
  296 + this.dragData.dragging = false;
  297 + off(window, 'mousemove', this.handleMoveMove);
  298 + off(window, 'mouseup', this.handleMoveEnd);
222 } 299 }
223 }, 300 },
224 mounted () { 301 mounted () {
src/styles/components/modal.less
@@ -44,6 +44,17 @@ @@ -44,6 +44,17 @@
44 &-no-mask{ 44 &-no-mask{
45 pointer-events: auto; 45 pointer-events: auto;
46 } 46 }
  47 + &-drag{
  48 + position: absolute;
  49 + .@{modal-prefix-cls}-header{
  50 + cursor: move;
  51 + }
  52 + }
  53 + &-dragging{
  54 + -webkit-user-select: none;
  55 + -moz-user-select: none;
  56 + user-select: none;
  57 + }
47 } 58 }
48 59
49 &-header { 60 &-header {