vue自定义指令,拖拽指令

347 阅读2分钟

前言

浏览论坛看到一个比较有趣的功能,涉及到了拖拽功能。自己也就查阅了下,试了试,做个小笔记。了解拖拽功能前先看看interact.js这个插件。

一、interact.js

interact.js 是一个 JavaScript 资源库提供拖,放,调整尺寸和多点触摸手势功能用于现代浏览器。它的免费和开源版本提供了强大的配置像惯性和指针、约束调整器。

interact.js Pro 使用更多的调节器扩展了该开源功能,更多复杂的内置交互,框架集成,和高级开发工具,用于节省您的事件和劳动力。

该资源库聚焦于 持续呈现指针输入事件 在不同的浏览器和设备,提供方便的方法 在用户鼠标指针没有移动的时候假装在移动 (吸附, 惯性, 等)。

interact 函数接收一个元素或者 CSS 选择器字符串,并返回一个 Interactable 拥有很多方法的对象用于配置动作和事件监听器。指针交互队列按下 -> 移动 -> 弹起,启动拖,调整尺寸,或手势动作。通过添加事件监听器方法,您可以为 InteractEvent 事件提供反馈,该事件包含了指针坐标,速度,元素大小等。

二、具体实现与使用

在mian.js里

    // 添加依赖interactjs
    // 在main.js中引入interactjs
    import interact from 'interactjs'
    
    Vue.directive('interact', {
      inserted(el, binding, vnode) {
        let val = binding.value
        let it = interact(el).draggable({
          listeners: {
            start(event) {
              let els = document.querySelectorAll('.cpt-dialog')
              for (let i = 0; i < els.length; i++) {
                els[i].style.zIndex = 10
              }
              el.style.zIndex = 20
            },
            move(event) {
              var target = event.target
              // keep the dragged position in the data-x/data-y attributes
              var x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx
              var y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy

              // translate the element
              target.style.webkitTransform = target.style.transform =
                'translate(' + x + 'px, ' + y + 'px)'

              // update the posiion attributes
              target.setAttribute('data-x', x)
              target.setAttribute('data-y', y)
            },
          },
          inertia: true,
          modifiers: [
            interact.modifiers.restrictRect({
              restriction: 'body',
              endOnly: true,
            }),
          ],
        })
        if (val && val.resize) {
          it.resizable({
            // resize from all edges and corners
            edges: { left: true, right: true, bottom: true, top: true },

            listeners: {
              move(event) {
                var target = event.target
                var x = parseFloat(target.getAttribute('data-x')) || 0
                var y = parseFloat(target.getAttribute('data-y')) || 0

                // update the element's style
                target.style.width = event.rect.width + 'px'
                target.style.height = event.rect.height + 'px'

                // translate when resizing from top or left edges
                x += event.deltaRect.left
                y += event.deltaRect.top

                target.style.webkitTransform = target.style.transform =
                  'translate(' + x + 'px,' + y + 'px)'

                target.setAttribute('data-x', x)
                target.setAttribute('data-y', y)
                // target.textContent = Math.round(event.rect.width) + '\u00D7' + Math.round(event.rect.height)
              },
            },
            modifiers: [
              // keep the edges inside the parent
              interact.modifiers.restrictEdges({
                outer: 'parent',
              }),

              // minimum size
              interact.modifiers.restrictSize({
                min: { width: 100, height: 50 },
              }),
            ],

            inertia: true,
          })
        }
      },
})