ElementUI的Dialog弹窗实现全局命令拖拽移动功能

首先创建elementui的dialog组件

<el-dialog
  title="提示"
  :visible.sync="dialogVisible"
  width="30%">
  <span>这是一段信息</span>
  <span slot="footer" class="dialog-footer">
    <el-button @click="dialogVisible = false">取 消</el-button>
    <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
  </span>
</el-dialog>

其次在src文件下创建utils文件,在utils文件下创建全局拖拽文件directive.js

import Vue from 'vue'
//弹窗全局拖动指令
Vue.directive('dialogDrag', {
    bind(el, binding, vnode, oldVnode) {
        const value = binding.value
        if (value == false) return
        // 获取拖拽内容头部
        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);
        dragDom.style.position = 'absolute';
        dragDom.style.marginTop = 0;
        let width = dragDom.style.width;
        if (width.includes('%')) {
            width = +document.body.clientWidth * (+width.replace(/\%/g, '') / 100);
        } else {
            width = +width.replace(/\px/g, '');
        }
        dragDom.style.left = `${(document.body.clientWidth - width) / 2}px`;
        // 鼠标按下事件
        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;

                let finallyL = l + styL
                let finallyT = t + styT

                // 移动当前元素
                dragDom.style.left = `${finallyL}px`;
                dragDom.style.top = `${finallyT}px`;

            };

            document.onmouseup = function (e) {
                document.onmousemove = null;
                document.onmouseup = null;
            };
        }
    }
})

 在main.js文件里面引用directive.js

mport Vue from 'vue'
import Element from 'element-ui'
import './styles/element-variables.scss'

import '@/styles/index.scss' // global css

import App from './App'
import store from './store'
import router from './router'

import i18n from './lang' // internationalization
import './icons' // icon
import './permission' // permission control
import './utils/error-log' // error log
import './utils/directive' //引入全局拖拽

import * as filters from './filters' // global filters

Vue.use(Element, {
  size: Cookies.get('size') || 'medium', // set element-ui default size
  i18n: (key, value) => i18n.t(key, value)
})
// register global utility filters
Object.keys(filters).forEach(key => {
  Vue.filter(key, filters[key])
})

Vue.config.productionTip = false

new Vue({
  el: '#app',
  router,
  store,
  i18n,
  render: h => h(App)
})

最后只需要在el-dialog组件上添加属性v-dialogDrag

<el-dialog title="提示" :visible.sync="dialogVisible" v-dialogDrag width="30%">
    <span>这是一段信息</span>
    <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
    </span>
</el-dialog>

现在这样效果是实现了,但是会有一个问题就是每次重新打开不是居中的有点小bug,可以直接v-if判断一下,条件和:visible.sync="dialogVisible"是一样的,这样每次关闭都回到原来的位置

<el-dialog title="提示" v-if="dialogVisible" :visible.sync="dialogVisible" v-dialogDrag width="30%">
    <span>这是一段信息</span>
    <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="dialogVisible = false">确 定</el-button>
    </span>
</el-dialog>

  • 8
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值