自定義拖拽div,不超出父級(jí)(使用自定義指令)

  • 在main.ts 文件中添加自定義指令
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import piniaStore from "@/store";
import "@/assets/styles/index.scss"
import {useAccountInfoStore} from "@/store/accountInfoStore";
InitCustomConfig().then(config => {
  const app = createApp(App)
      .use(piniaStore)
      .use(router)
      .use(i18n)
  document.title = config.logoConfig?.systemTitle ?? ""
  // 自定義指令--拖拽
  app.directive('drag',(el) => {
    let oDiv = el // 當(dāng)前元素
    // let self = this // 上下文
    // 禁止選擇網(wǎng)頁(yè)上的文字
    document.onselectstart = function () {
      return false
    }
    oDiv.onmousedown = function (e:any) {
      oDiv.style.cursor = 'move'
      let parentWidth = oDiv.parentElement.offsetWidth
      let parentHeight = oDiv.parentElement.offsetHeight
      let oDivWidth = oDiv.offsetWidth
      let oDivHeight = oDiv.offsetHeight
      // 鼠標(biāo)按下,計(jì)算當(dāng)前元素距離可視區(qū)的距離
      let disX = e.clientX - oDiv.offsetLeft
      let disY = e.clientY - oDiv.offsetTop
      document.onmousemove = function (e) {
        let left:number = e.clientX - disX
        let top:number = e.clientY - disY
        // 通過(guò)事件委托,計(jì)算移動(dòng)的距離
        if(left < 0) {
          left = 0
        }
        if(top < 0) {
          top = 0
        }
        if(left + oDivWidth > parentWidth) {
          left = parentWidth - oDivWidth
        }
        if(top + oDivHeight > parentHeight) {
          top = parentHeight - oDivHeight
        }
        let right = parentWidth - left - oDivWidth
        let bottom = parentHeight - top - oDivHeight
        //移動(dòng)當(dāng)前元素
        oDiv.style.right = right + "px";
        // oDiv.style.bottom = bottom + "px";
        oDiv.style.top = top + "px";
      }
      document.onmouseup = function (e) {
        oDiv.style.cursor = 'default'
        document.onmousemove = null
        document.onmouseup = null
      }
      // return false不加的話(huà)可能導(dǎo)致黏連,就是拖到一個(gè)地方時(shí)div粘在鼠標(biāo)上不下來(lái),相當(dāng)于onmouseup失效
      return false
    }
    }
  );
  // 自定義指令--按鈕權(quán)限
  app.directive('permission',
    (el, binding) => {
      if (useAccountInfoStore().account.authority) {
        if (useAccountInfoStore().account.authority?.indexOf(binding.value) === -1 && useAccountInfoStore().account.authority?.indexOf("admin") === -1) {
          el.parentNode && el.parentNode.removeChild(el)
        }
      }
    }
  );

}).catch(err => {
  console.log(err);
})

  • 在組件中使用
<template>
<div class="parents-box" v-drag >
  <div class="sub-box">
    可拖拽盒子
  </div>
  
</div>
</template>
<script lang='ts' setup>
import { ref, reactive,watch } from 'vue'
import { $ref } from 'vue/macros';

</script>
<style scoped lang='scss'>
.parents-box {
  width: 100%;
  height: 100%;
  position: relative;
  .sub-box{
     position: absolute;
     right: 10px;                   
     top: 10px;
     width: 300px;
     height: 200px;
     user-select: none;
     z-index: 2; 
  }
}
</style>

  • 注意:
    1.在定義自定義拖拽指令時(shí)設(shè)置 oDiv.style.right/oDiv.style.left oDiv.style.top/oDiv.style.bottom 的方向 在div元素上使用的時(shí)候css中的 right/left top/bottom 也需要保持一致 (要使用position: absolute;)
    2.使用的div元素 css中 z-index需要設(shè)置的大一些 避免權(quán)重不夠 拖拽時(shí)導(dǎo)致沒(méi)有效果
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容