vue自定义拖动弹框指令

1、在main.js同级目录下新建
directives.js文件

// directives.js
import Vue from 'vue'

// v-dialogDrag: 弹窗拖拽   Vue.directive    vue自定义指令
Vue.directive('dialogDrag', {
  bind(el, binding, vnode, oldVnode) {
    // 获取拖拽内容头部
    const dialogHeaderEl = el.querySelector('.el-dialog__header')
    // 获取拖拽内容整体 这个rrc-dialog是我自己封装的组件 如果使用element的组件应写成.el-dialog
    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

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

        // 边界值判定 注意clientWidth scrollWidth区别 要减去之前的top left值
        // dragDom.offsetParent表示弹窗阴影部分
        if (finallyL < 0 - 1.2 * dragDom.clientWidth - dragDom.offsetParent.offsetLeft) {
          finallyL = 0 - 1.2 * dragDom.clientWidth - dragDom.offsetParent.offsetLeft
        } else if (finallyL > dragDom.offsetParent.clientWidth - 2.4 * dragDom.clientWidth - dragDom.offsetParent.offsetLeft) {
          finallyL = dragDom.offsetParent.clientWidth - 2.4 * dragDom.clientWidth - dragDom.offsetParent.offsetLeft
        }

        if (finallyT < 0 - 0.5 * dragDom.clientHeight - dragDom.offsetParent.offsetLeft) {
          finallyT = 0 - 0.5 * dragDom.clientHeight - dragDom.offsetParent.offsetLeft
        } else if (finallyT > dragDom.offsetParent.clientHeight - 1.5 * dragDom.clientHeight - dragDom.offsetParent.offsetLeft) {
          finallyT = dragDom.offsetParent.clientHeight - 1.5 * dragDom.clientHeight - dragDom.offsetParent.offsetLeft
        }

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

        // 将此时的位置传出去
        // binding.value({x:e.pageX,y:e.pageY})
      }

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

2、在main.js中引入

<template>
  <div id="app">
    <router-view/>
  </div>
</template>

<script>
export default {
  name: 'App',
  created() {
    this.reset()
  },
  beforeDestory() {
    localStorage.clear()
    clearInterval(this.reset())
  },
  methods: {
    reset() {
      // 每隔36000000毫秒清空本地缓存
      const item = window.setInterval(() => {
        console.log(1111)
        localStorage.clear()
      }, 36000000)
      return item
    }
  }
}
</script>

3、使用

<el-dialog v-dialogDrag :append-to-body="true" :close-on-click-modal="false" :before-close="cancel" :visible.sync="dialog" title="查询" width="500px" >
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
你可以通过以下步骤来自定义全局弹框: 1. 在项目中新建一个全局弹框组件,例如 `GlobalDialog.vue`。 2. 在 `main.js` 中导入该组件并注册为全局组件: ```javascript import GlobalDialog from '@/components/GlobalDialog.vue' Vue.component('global-dialog', GlobalDialog) ``` 3. 在需要使用弹框的组件中,使用 `$emit` 方法触发一个事件,例如 `open-dialog`: ```javascript // 在组件中 this.$emit('open-dialog', { title: '弹框标题', content: '弹框内容', confirmText: '确认按钮文字', cancelText: '取消按钮文字', onConfirm: () => { // 确认按钮回调 }, onCancel: () => { // 取消按钮回调 } }) ``` 4. 在 `App.vue` 中监听该事件并显示全局弹框: ```html <template> <div id="app"> <global-dialog v-if="dialogVisible" :title="dialogTitle" :content="dialogContent" :confirm-text="confirmText" :cancel-text="cancelText" @confirm="dialogOnConfirm" @cancel="dialogOnCancel" ></global-dialog> <router-view @open-dialog="showDialog"></router-view> </div> </template> <script> export default { name: 'App', data() { return { dialogVisible: false, dialogTitle: '', dialogContent: '', confirmText: '', cancelText: '', dialogOnConfirm: () => {}, dialogOnCancel: () => {} } }, methods: { showDialog(data) { this.dialogTitle = data.title this.dialogContent = data.content this.confirmText = data.confirmText || '确定' this.cancelText = data.cancelText || '取消' this.dialogOnConfirm = data.onConfirm || (() => {}) this.dialogOnCancel = data.onCancel || (() => {}) this.dialogVisible = true } } } </script> ``` 这样就可以在任何需要使用全局弹框的组件中,通过 `$emit` 方法触发 `open-dialog` 事件,并传递弹框的相关参数来显示全局弹框了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值