
项目开发过程中我们通常会遇到需要到一些弹窗鼠标可以随意拖动位置去放置,vue里面直接通过封装对应的指令即可,于是封装了一个出来,希望可以用到。
Vue.directive('draggable-dom', draggableDom);
组件节点添加对应指令就可以
v-draggable-dom="{zIndex: 999, top: 10, left: 50}"
<div class="search-bar" ref="seachBar" :style="{ width }" v-draggable-dom="{zIndex: 999, top: 10, left: 50}">
指令代码:
/**
 * 拖拽元素指令
 * @param { Number } top  // 初始位置top 坐标 默认为元素本身的top
 * @param { Number } left  // 初始位置left 坐标 默认为元素本身的left
 * @param { Number } zIndex  // 层级,默认为9999
 */
export const draggableDom = {
  bind(el, binding, vnode) {
    // 初始化变量
    let startX = 0; // 鼠标按下时的初始 X 坐标
    let startY = 0; // 鼠标按下时的初始 Y 坐标
    let initialLeft = 0; // 元素的初始 left 值
    let initialTop = 0; // 元素的初始 top 值
    let isDragging = false; // 拖拽状态
    if (binding.value?.position) {
      e.style.position = binding.value?.position;
    }
    // 如果属性定位没有的时候则设置绝对定位
    const position = window.getComputedStyle(el);
    if (!position || position == 'static') {
      e.style.position = "absolute";
    }
    // el.style.cursor = "move"; // 设置鼠标样式为移动图标
    // 默认层级,默认为9999
    el.style.zIndex = binding?.value?.zIndex || 9999;
    // 传入top值
    if (binding.value?.top) {
      // let top = el.getBoundingClientRect().top;
      let top = binding.value?.top;
      el.style.top = `${top}px`;
    }
    // 传入left值
    if (binding.value?.left) {
      // let left = el.getBoundingClientRect().left;
      let left = binding.value?.left;
      el.style.left = `${left}px`;
    }
    // 鼠标按下事件处理函数
    const onMouseDown = (event) => {
      // 防止文本选择
      // event.preventDefault();
      // 记录初始鼠标位置和元素位置
      startX = event.clientX;
      startY = event.clientY;
      initialLeft = el.offsetLeft;
      initialTop = el.offsetTop;
      isDragging = true; // 开启拖拽状态
      // 监听 mousemove 和 mouseup 事件
      document.addEventListener("mousemove", onMouseMove);
      document.addEventListener("mouseup", onMouseUp);
    };
    // 鼠标移动事件处理函数
    const onMouseMove = (event) => {
      if (!isDragging) return; // 如果未处于拖拽状态,直接返回
      // 计算鼠标的位移
      const moveX = event.clientX - startX;
      const moveY = event.clientY - startY;
      // 更新元素的位置
      el.style.left = initialLeft + moveX + "px";
      el.style.top = initialTop + moveY + "px";
    };
    // 鼠标松开事件处理函数
    const onMouseUp = () => {
      isDragging = false; // 关闭拖拽状态
      // 移除事件监听器
      document.removeEventListener("mousemove", onMouseMove);
      document.removeEventListener("mouseup", onMouseUp);
    };
    // 绑定 mousedown 事件
    el.style.position = "absolute"; // 确保元素是绝对定位
    el.addEventListener("mousedown", onMouseDown);
  },
  // 解绑指令
  unbind(el) {
    // 移除 mousedown 事件监听器
    el.removeEventListener("mousedown", onMouseDown);
  },
};









![Postman[7] 内置动态参数及自定义的动态参数](https://i-blog.csdnimg.cn/direct/0eb7deeff3504efead4426d1cac5ae7f.png)









