vue 使用自定义指令实现拖拽

本文介绍如何在Vue中使用自定义指令来实现拖拽功能,满足灵活的DOM元素拖动和样式修改需求。通过自定义事件和监听器,结合Vuex进行状态管理,确保组件间的通信,实现复杂拖拽场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

vue 使用自定义指令实现拖拽

需求背景,工作中需要实现一个自定义打印模板的需求,能够实现单个及多个dom元素的同时拖拽,也能通过外部的input元素修改dom元素的样式。在npm和GitHub上找了各种已有的vue组件,不够灵活,效果都不是自己想要的

  1. vue自定义指令
Vue.directive('dragx', (el, binding, vnode) => {
   
  //  默认参数
  let defaultOpts = {
   
    dragDirection: 'n, e, s, w, ne, se, sw, nw, all',
    dragContainerId: '', //
    dragBarClass: '', // 类选择器
    canDrag: true,
    canResize: true,
    multiSelect: false
  }
  let isMove = false
  let isResize = false
  let constraintDom
  let constraintRect
  let constraintRectHeight
  let constraintRectWidth
  binding.value = binding.value || {
   }
  let cfg = Object.assign({
   }, defaultOpts, binding.value)
  if (cfg.dragContainerId) {
   
    constraintDom = document.querySelector('#' + cfg.dragContainerId)
    constraintRect = constraintDom.getBoundingClientRect()
    constraintRectHeight = constraintRect.height
    constraintRectWidth = constraintRect.width
  }

  let getStyleNumValue = (style, key) => parseInt(style.getPropertyValue(key), 10)
  //  设置约束范围
  function setConstraint (data) {
   
    if (cfg.dragContainerId) {
   
      if (data.left <= 0) data.left = 0
      if (data.top <= 0) data.top = 0
      if (data.top + data.height + data.borderTop + data.borderBottom >= constraintRectHeight) data.top = constraintRectHeight - data.height - data.borderTop - data.borderBottom
      if (data.left + data.width + data.borderLeft + data.borderRight > constraintRectWidth) data.left = constraintRectWidth - data.width - data.borderLeft - data.borderRight
    }
  }

  el.onmousemove = e => {
   
    if (cfg.dragBarClass.length > 0 && e.target.classList.contains(cfg.dragBarClass) && cfg.canDrag) {
   
      el.style.cursor = 'move'
      return
    }
    el.style.cursor = ''
  }

  el.onmouseleave = e => {
   
    el.style.cursor = ''
  }

  el.onmousedown = e => {
   
    let clickId = (e.target || e.srcElement).id
    let posData = {
   
      x: e.pageX, y: e.pageY
    }
    el.onmouseup = e => {
   
      // dom元素选中时发送active事件
      if (!cfg.active) el.dispatchEvent(new CustomEvent('bindActive', 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值