vue3创建可拖拽自定义指令(拖拽组件)

main.js


import diyVueDirectives from "@/utils/dragGss"


const app = createApp(App)

app.use(diyVueDirectives)


app.mount('#app')

dragGss.js

const drag = {
  mounted(el, binding) {
    const addV = (v1, v2) => {
      const x = v1[0] + v2[0];
      const y = v1[1] + v2[1];
      return [x, y];
    };
    const minusV = (v1, v2) => {
      const x = v2[0] - v1[0];
      const y = v2[1] - v1[1];
      return [x, y];
    };
    const formatV = (v, range) => {
      let x = v[0];
      let y = v[1];
      x = Math.max(x, range[2]);
      x = Math.min(x, range[3]);
      y = Math.max(y, range[0]);
      y = Math.min(y, range[1]);
      return [x, y];
    };
    const setTranslatePosition = (transform, v) => {
      return `translate(${v[0]}px, ${v[1]}px)`;
    };
    const getPosition = (e) => {
      if (e instanceof MouseEvent) {
        return [e.pageX, e.pageY];
      }
      const touch = e.touches[0];
      return [touch.pageX, touch.pageY];
    };
    const enableDrag = (element) => {
      let { outerElement, innerElement } = {};
      let startTransform = window.getComputedStyle(element).transform;
      let startPosition = null;
      let endPosition = null;
      let draggingMoveVectorRange = null;
      let draggedMoveVector = [0, 0];
      let draggingMoveVector = [0, 0];
      outerElement = document.body;
      innerElement = element;
      const onMouseDown = (e) => {
        e.stopPropagation();
        startPosition = getPosition(e);
        if (outerElement && element) {
          const outerElementRect = outerElement.getBoundingClientRect();
          const elementRect = element.getBoundingClientRect();
          draggingMoveVectorRange = [outerElementRect.top - elementRect.top, outerElementRect.bottom - elementRect.bottom, outerElementRect.left - elementRect.left, outerElementRect.right - elementRect.right];
        }
      };
      const onMouseMove = (e) => {
        if (startPosition && draggingMoveVectorRange) {
          endPosition = getPosition(e);
          const currentMoveVector = formatV(minusV(startPosition, endPosition), draggingMoveVectorRange);
          draggingMoveVector = addV(draggedMoveVector, currentMoveVector);
          element.style.transform = setTranslatePosition(startTransform, draggingMoveVector);
        }
      };
      const onMouseUp = (e) => {
        if (startPosition && draggingMoveVectorRange) {
          draggedMoveVector = draggingMoveVector;
        }
        startPosition = null;
      };
      const addEventListener = () => {
        if (innerElement) {
          innerElement.addEventListener("mousedown", onMouseDown);
          document.addEventListener("mousemove", onMouseMove);
          document.addEventListener("mouseup", onMouseUp);
        }
      };
      const removeEventListener = () => {
        if (innerElement) {
          innerElement.removeEventListener("mousedown", onMouseDown);
          document.removeEventListener("mousemove", onMouseMove);
          document.removeEventListener("mouseup", onMouseUp);
        }
      };
      addEventListener();
      return removeEventListener;
    };
    enableDrag(el);
  },
  unmounted(el, binding, vnode, prevVnode) {
    // el.removeEventListener("mousedown", onMousedown);
  },
};
/**
 * 定义指令集
 */
const diyVueDirectives = {
  install: function (app) {
    app.directive('drag', drag) // 注册自定义拖拽指令
  }
}
 
/**
 * 导出指令集
 */
export default diyVueDirectives

在dom标签的使用

//这时这个div就可以随意拖动了

<div v-drag>
2222
</div>


//这个也可以直接放组件上,这样组件也可以拖动,实现可拖拽的dialog弹窗
//组件里面写弹窗要展示的东西
<demo v-drag ref="demoRef" v-if="flag" />
<demo v-drag ref="demoRef" v-if="flag" />

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值