1、在Vue项目中src/utils目录中创建dialog.js,用来定义draggable-dialog;
import Vue from 'vue'
Vue.directive('draggable-dialog', { // 属性名称draggable-dialog,前面加v- 使用bind(el, binding, vnode) {const dialogHeaderEl = el.querySelector('.el-dialog__header')const dragDom = el.querySelector('.el-dialog')dialogHeaderEl.style.cssText += ';cursor:move;'dragDom.style.cssText += ';top:0px;'// 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null);const getStyle = (function () {if (window.document.currentStyle) {return (dom, attr) => dom.currentStyle[attr]} else {return (dom, attr) => getComputedStyle(dom, false)[attr]}})()dialogHeaderEl.onmousedown = (e) => {// 鼠标按下,计算当前元素距离可视区的距离const disX = e.clientX - dialogHeaderEl.offsetLeftconst disY = e.clientY - dialogHeaderEl.offsetTopconst dragDomWidth = dragDom.offsetWidth// const dragDomHeight = dragDom.offsetHeightconst screenWidth = document.body.clientWidthconst screenHeight = document.body.clientHeightconst minDragDomLeft = dragDom.offsetLeftconst maxDragDomLeft = screenWidth - dragDom.offsetLeft - dragDomWidthconst minDragDomTop = dragDom.offsetTop// const maxDragDomTop = screenHeight - dragDom.offsetTop - dragDomHeightconst maxDragDomTop = screenHeight - dragDom.offsetTop// 不需要-dragDomHeight// 获取到的值带px 正则匹配替换let styL = getStyle(dragDom, 'left')let styT = getStyle(dragDom, 'top')if (styL.includes('%')) {styL = +document.body.clientWidth * (+styL.replace(/\%/g, '') / 100)styT = +document.body.clientHeight * (+styT.replace(/\%/g, '') / 100)} else {styL = +styL.replace(/\px/g, '')styT = +styT.replace(/\px/g, '')}document.onmousemove = function (e) {// 通过事件委托,计算移动的距离let left = e.clientX - disXlet top = e.clientY - disY// 边界处理if (-(left) > minDragDomLeft) {left = -minDragDomLeft} else if (left > maxDragDomLeft) {left = maxDragDomLeft}if (-(top) > minDragDomTop) {top = -minDragDomTop} else if (top > maxDragDomTop) {top = maxDragDomTop}// 移动当前元素dragDom.style.cssText += `;left:${left + styL}px;top:${top + styT}px;`// emit onDrag eventvnode.child.$emit('draggable-dialog')}document.onmouseup = function (e) {document.onmousemove = nulldocument.onmouseup = null}}}
})
2、 在main.js文件中引入dialog.js,代码如下:
import Vue from 'vue'
import App from './App'
import router from './router'
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
import '@/utils/dialog.js'Vue.use(ElementUI)Vue.config.productionTip = false/* eslint-disable no-new */
new Vue({el: '#app',router,components: { App },template: '<App/>'
})
3、页面中的el-dialog标签上添加v-draggable-dialog
<el-dialogid="dragDialog"v-draggable-dialog:fullscreen="dialogFullScreen":v-if="showDialog":visible.sync="showDialog"title="查看"><template slot="title"><div class="custom_dialog_header"><span class="el_dialog_title">查看详情</span><div class="custom_dialog_menu" @click="screenClick"><i class="el-icon-full-screen"></i></div></div></template><div>展示内容</div ></el-dialog>//全屏 定义属性
dialogFullScreen: false
showDialog: false
//全屏用的方法
screenClick() {this.$nextTick(() => {this.dialogFullScreen = !this.dialogFullScreenconst dialog = document.querySelector('#dragDialog .el-dialog')dialog.style.left = '0'dialog.style.top = '0'})}
//如果 移动弹窗位置,第二次点击没有居中,可以在打开弹窗时,调用recoveryPosition方法
recoveryPosition() {this.$nextTick(() => {const dialog = document.querySelectorAll('.el-dialog__wrapper .el-dialog')if (dialog.length > 0) {dialog.forEach((item) => {item.style.left = '0'item.style.top = '0'})}})},
//全屏样式
::v-deep.custom_dialog_header {display: flex;justify-content: space-between;
}
::v-deep .custom_dialog_menu {padding: 7px 30px 0 0;
}
::v-deep .custom_dialog_menu i {color: #909399;font-size: 15px;
}
::v-deep.el-icon-full-screen {cursor: pointer;
}
说明:v-draggable-dialog 是移动位置用的 fullscreen 是全屏的属性 添加全屏功能 要加id dragDialog