Element Dialog
Element Dialog 对话框,自身不带拖拽功能,需要添加。
dialogDrag.js
/* eslint-disable */
import Vue from 'vue'
// v-dialogDrag: 弹窗拖拽
Vue.directive('dialogDrag', {
bind(el, binding, vnode, oldVnode) {
const dialogHeaderEl = el.querySelector('.el-dialog__header')
const dragDom = el.querySelector('.el-dialog')
dialogHeaderEl.style.cursor = 'move'
// 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null)
const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null)
dialogHeaderEl.onmousedown = (e) => {
// 鼠标按下,计算当前元素距离可视区的距离
const disX = e.clientX - dialogHeaderEl.offsetLeft
const disY = e.clientY - dialogHeaderEl.offsetTop
// 获取到的值带px 正则匹配替换
let styL, styT
// 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px
if (sty.left.includes('%')) {
styL = +document.body.clientWidth * (+sty.left.replace(/\%/g, '') / 100)
styT = +document.body.clientHeight * (+sty.top.replace(/\%/g, '') / 100)
} else {
styL = +sty.left.replace(/\px/g, '')
styT = +sty.top.replace(/\px/g, '')
}
document.onmousemove = function (e) {
// 通过事件委托,计算移动的距离
const l = e.clientX - disX
const t = e.clientY - disY
// 移动当前元素
dragDom.style.left = `${l + styL}px`
dragDom.style.top = `${t + styT}px`
// 将此时的位置传出去
// binding.value({x:e.pageX,y:e.pageY})
}
document.onmouseup = function (e) {
document.onmousemove = null
document.onmouseup = null
}
}
}
})
main.js
import '@/dialog.js'
.vue
<el-dialog title="'title'"
v-dialogDrag
:visible.sync="dialogVisible"
width="30%" center>
content
</el-dialog>
View UI Modal
View UI 的弹窗支持拖拽功能,多个弹窗也互不影响,如果项目使用的是 Element,可以按需加载 View UI 的弹窗组件。
npm install view-design --save
npm install babel-plugin-import --save-dev
vue-cli2 项目
.babelrc
{
"presets": [],
"plugins": [["import", {
"libraryName": "view-design",
"libraryDirectory": "src/components"
}]]
}
vue-cli3 项目没有 .babelrc 文件,在 babel.config.js 文件中添加上面代码:
babel.config.js
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
],
plugins: [
["import", {
"libraryName": "view-design",
"libraryDirectory": "src/components"
}]
]
}
main.js
import 'view-design/dist/styles/iview.css'
import { Modal } from 'view-design'
Vue.component('Modal', Modal)
防止 iview.css 影响项目原本样式,单独加 Modal 的样式:
.ivu-modal {
width: auto;
margin: 0 auto;
position: relative;
outline: 0;
top: 100px
}
.ivu-modal-hidden {
display: none !important
}
.ivu-modal-wrap {
position: fixed;
overflow: auto;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1000;
-webkit-overflow-scrolling: touch;
outline: 0
}
.ivu-modal-wrap * {
box-sizing: border-box;
-webkit-tap-highlight-color: transparent
}
.ivu-modal-mask {
position: fixed;
top: 0;
bottom: 0;
left: 0;
right: 0;
height: 100%;
z-index: 1000
}
.ivu-modal-mask-hidden {
display: none
}
.ivu-modal-content {
position: relative;
border: 0;
}
.ivu-modal-content-no-mask {
pointer-events: auto
}
.ivu-modal-content-drag {
position: absolute
}
.ivu-modal-content-drag .ivu-modal-header {
cursor: move
}
.ivu-modal-content-dragging {
user-select: none
}
.ivu-modal-header p,
.ivu-modal-header-inner {
display: inline-block;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap
}
.ivu-modal-close {
z-index: 1;
position: absolute;
right: 8px;
top: 8px;
overflow: hidden;
cursor: pointer
}
.ivu-modal-close .ivu-icon-ios-close {
transition: color .2s ease;
position: relative;
top: 1px
}
.ivu-modal-close .ivu-icon-ios-close:hover {
color: #444
}
.ivu-modal-fullscreen {
width: 100% !important;
top: 0;
bottom: 0;
position: absolute
}
.ivu-modal-fullscreen .ivu-modal-content {
width: 100%;
position: absolute;
top: 0;
bottom: 0
}
.ivu-modal-fullscreen .ivu-modal-body {
width: 100%;
overflow: auto;
position: absolute;
top: 51px;
bottom: 61px
}
.ivu-modal-fullscreen-no-header .ivu-modal-body {
top: 0
}
.ivu-modal-fullscreen-no-footer .ivu-modal-body {
bottom: 0
}
.ivu-modal-fullscreen .ivu-modal-footer {
position: absolute;
width: 100%;
bottom: 0
}
.ivu-modal-no-mask {
pointer-events: none
}
.vue
<Modal v-model="modalVisible" draggable
scrollable title="'title'">
<div>content</div>
</Modal>