Vue-cli中实现拖拽-自定义指令

附加条件:不能超出父元素

实现思路: 使用vue自定义指令directives, 监听鼠标按下事件,计算按下时目标元素与父元素的距离,最后通过CSS position-absolute : left / top实现距离改变

(父元素需要有宽高,且有position定位)

1、vue文件中实现

使用directives

template中使用指令

script中定义指令

ini 复制代码
methods: {},
directives: {
  drag: {
    inserted: function(el) {
      // console.log('el:', el)
      let oDiv = el; // 当前元素
      // 禁止选择拖拽块上的文字
      document.onselectstart = function () {
        return false;
      };
      oDiv.onmousedown = function (e) {
        // 获取父元素dom
        let pbox = document.getElementById('video-wrap-hls')
        // console.log('parent-box', pbox.clientWidth, pbox.clientHeight)
        // console.log('child-box', oDiv.clientWidth, oDiv.clientHeight)
        // console.log('e:', e, oDiv.offsetLeft, oDiv.offsetTop)
        // 鼠标按下,计算当前元素距离可视区的距离
        let disX = e.clientX - oDiv.offsetLeft;
        let disY = e.clientY - oDiv.offsetTop;
        document.onmousemove = function (e) {
          // 通过事件委托,计算移动的距离
          let l = e.clientX - disX;
          let t = e.clientY - disY;
          if (l < 0) {
            l = 0
          } else if (l > (pbox.clientWidth - oDiv.clientWidth)) {
            l = pbox.clientWidth - oDiv.clientWidth
          }
          if (t < 0) {
            t = 0
          } else if (t > (pbox.clientHeight - oDiv.clientHeight)) {
            t = pbox.clientHeight - oDiv.clientHeight
          }
          // 移动当前元素
          oDiv.style.left = l + "px";
          oDiv.style.top = t + "px";
        };
        document.onmouseup = function (e) {
          document.onmousemove = null;
          document.onmouseup = null;
        };
        // 防止黏连
        return false;
      };
    },
  }
},

2、main.js全局引入

创建directives.js 在入口文件引入 并Vue.use,实现代码与文件内实现基本相同。

vue官方directive使用方法

from vue官网

from vue官网

项目中使用

在入口文件引入并使用

上述步骤完成后可直接在页面文件中使用

3、小坑

需注意如果css使用了transition过渡, 不能使用all 因为 left / top 改变也会发生过渡 导致发生拖拽延迟效果

如果需要鼠标hover后有动画效果 可以分别写出来

栗子

相关推荐
金金金__1 小时前
Element-Plus:popconfirm与tooltip一起使用不生效?
前端·vue.js·element
前端梭哈攻城狮1 小时前
uniapp图片上传添加水印/压缩/剪裁
前端·javascript·vue.js
踢足球的,程序猿2 小时前
从 Vue 2.0 进阶到 Vue 3.0 的核心技术解析指南
前端·javascript·vue.js·前端框架·html
掘金安东尼4 小时前
仅仅是发送一封邮件?暴露安全边界!
javascript·vue.js·面试
bo521004 小时前
突破性能瓶颈:基于虚拟滚动的大数据需求文档方案——告别卡顿与分页,实现Word级流畅体验
javascript·vue.js
小张快跑。4 小时前
【Vue3】(三)vue3中的pinia状态管理、组件通信
前端·javascript·vue.js
一颗奇趣蛋5 小时前
vue性能优化(响应数据&静态数据)
vue.js·性能优化
Hilaku5 小时前
用好了 defineProps 才叫会用 Vue3,90% 的写法都错了
前端·javascript·vue.js
Dignity_呱5 小时前
vue3对组件通信做了哪些升级?
前端·vue.js·面试
独立开阀者_FwtCoder5 小时前
最全301/302重定向指南:从SEO到实战,一篇就够了
前端·javascript·vue.js