Commit d4b59a9adbeacacf4ed8c4e2d55f3954227bc4da

Authored by 梁灏
1 parent 1c7289e9

Modal add dragable prop

examples/routers/modal.vue
... ... @@ -5,7 +5,7 @@
5 5 <Modal
6 6 v-model="modal1"
7 7 title="Common Modal dialog box title"
8   - :mask="false"
  8 + dragable
9 9 @on-ok="ok"
10 10 @on-cancel="cancel">
11 11 <p>Content of dialog</p>
... ...
src/components/modal/modal.vue
... ... @@ -6,13 +6,16 @@
6 6 <div :class="wrapClasses" @click="handleWrapClick">
7 7 <transition :name="transitionNames[0]" @after-leave="animationFinish">
8 8 <div :class="classes" :style="mainStyles" v-show="visible">
9   - <div :class="contentClasses">
  9 + <div :class="contentClasses" ref="content" :style="contentStyles">
10 10 <a :class="[prefixCls + '-close']" v-if="closable" @click="close">
11 11 <slot name="close">
12 12 <Icon type="ios-close"></Icon>
13 13 </slot>
14 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 19 <div :class="[prefixCls + '-body']"><slot></slot></div>
17 20 <div :class="[prefixCls + '-footer']" v-if="!footerHide">
18 21 <slot name="footer">
... ... @@ -34,6 +37,8 @@
34 37 import Emitter from '../../mixins/emitter';
35 38 import ScrollbarMixins from './mixins-scrollbar';
36 39  
  40 + import { on, off } from '../../utils/dom';
  41 +
37 42 const prefixCls = 'ivu-modal';
38 43  
39 44 export default {
... ... @@ -115,7 +120,14 @@
115 120 wrapShow: false,
116 121 showHead: true,
117 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 133 computed: {
... ... @@ -146,7 +158,9 @@
146 158 return [
147 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 168 let style = {};
155 169  
156 170 const width = parseInt(this.width);
157   - const styleWidth = {
  171 + const styleWidth = this.dragData.x !== null ? {
  172 + top: 0
  173 + } : {
158 174 width: width <= 100 ? `${width}%` : `${width}px`
159 175 };
160 176  
... ... @@ -164,6 +180,22 @@
164 180  
165 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 199 localeOkText () {
168 200 if (this.okText === undefined) {
169 201 return this.t('i.modal.okText');
... ... @@ -219,6 +251,51 @@
219 251 },
220 252 animationFinish() {
221 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 301 mounted () {
... ...
src/styles/components/modal.less
... ... @@ -44,6 +44,17 @@
44 44 &-no-mask{
45 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 60 &-header {
... ...