feat: 增加弹窗拖动功能
This commit is contained in:
parent
ecc8d6d4dc
commit
b1eca82a88
|
@ -1,9 +1,10 @@
|
|||
<template>
|
||||
<a-modal
|
||||
:class="'custom-modal' + (innerFullscreen ? ' fullscreen' : '')"
|
||||
:class="['custom-modal', innerFullscreen ? ' fullscreen' : '', moveable ? 'moveable' : '']"
|
||||
v-bind="_attrs"
|
||||
v-model="visible"
|
||||
:maskClosable="false"
|
||||
v-drag-modal="moveable"
|
||||
@cancel="handleCancel"
|
||||
>
|
||||
<img slot="closeIcon" src="@/assets/images/global/close.png" />
|
||||
|
@ -46,6 +47,10 @@ export default {
|
|||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
moveable: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -157,4 +162,21 @@ export default {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.moveable {
|
||||
::v-deep {
|
||||
.ant-modal-mask,
|
||||
.ant-modal-wrap {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.ant-modal-mask {
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.ant-modal-wrap {
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
57
src/directives/dragModal.js
Normal file
57
src/directives/dragModal.js
Normal file
|
@ -0,0 +1,57 @@
|
|||
import Vue from 'vue'
|
||||
|
||||
// 注册自定义拖拽指令,弥补 modal 组件不能拖动的缺陷
|
||||
Vue.directive('drag-modal', (el, bindings, vnode) => {
|
||||
if (!bindings.value) {
|
||||
return
|
||||
}
|
||||
|
||||
Vue.nextTick(() => {
|
||||
const { visible, destroyOnClose } = vnode.componentInstance
|
||||
// 防止未定义 destroyOnClose 关闭弹窗时dom未被销毁,指令被重复调用
|
||||
if (!visible) return
|
||||
const modal = el.getElementsByClassName('ant-modal')[0]
|
||||
const header = el.getElementsByClassName('ant-modal-header')[0]
|
||||
let left = 0
|
||||
let top = 0
|
||||
|
||||
// 设置遮罩层可滚动
|
||||
setTimeout(() => {
|
||||
document.body.style.width = '100%'
|
||||
document.body.style.overflowY = 'inherit'
|
||||
}, 0)
|
||||
|
||||
// 鼠标变成可移动的指示
|
||||
header.style.cursor = 'move'
|
||||
|
||||
// 未定义 destroyOnClose 时,dom未被销毁,关闭弹窗再次打开,弹窗会停留在上一次拖动的位置
|
||||
if (!destroyOnClose) {
|
||||
left = modal.left || 0
|
||||
top = modal.top || 0
|
||||
}
|
||||
// top 初始值为 offsetTop
|
||||
top = top || modal.offsetTop
|
||||
header.onmousedown = e => {
|
||||
const startX = e.clientX
|
||||
const startY = e.clientY
|
||||
header.left = header.offsetLeft
|
||||
header.top = header.offsetTop
|
||||
el.onmousemove = event => {
|
||||
const endX = event.clientX
|
||||
const endY = event.clientY
|
||||
modal.left = header.left + (endX - startX) + left
|
||||
modal.top = header.top + (endY - startY) + top
|
||||
modal.style.left = modal.left + 'px'
|
||||
modal.style.top = modal.top + 'px'
|
||||
}
|
||||
el.onmouseup = event => {
|
||||
left = modal.left
|
||||
top = modal.top
|
||||
el.onmousemove = null
|
||||
el.onmouseup = null
|
||||
header.releaseCapture && header.releaseCapture()
|
||||
}
|
||||
header.setCapture && header.setCapture()
|
||||
}
|
||||
})
|
||||
})
|
|
@ -68,6 +68,8 @@ import 'vue-resize/dist/vue-resize.css'
|
|||
import VueResize from 'vue-resize'
|
||||
Vue.use(VueResize)
|
||||
|
||||
import './directives/dragModal'
|
||||
|
||||
Vue.prototype.rules = rules
|
||||
Vue.config.productionTip = false
|
||||
Vue.use(Storage, config.storageOptions)
|
||||
|
|
Loading…
Reference in New Issue
Block a user