1. 程式人生 > 其它 >Vue 自定義指令實現元素拖動

Vue 自定義指令實現元素拖動

昨天在做的一個功能時,同時彈出多個框展示多個表格資料。

這些彈出框可以自由拖動。單獨的拖動好實現,給元素繫結 mousedowm 事件。

這裡就想到了 Vue 裡面自定義指令來實現。

一、自定義指令

在使用自定義指令之前,先對自定義指令有一定的瞭解。從以下幾個方面著手:

1、自定義指令定義範圍

全域性註冊和元件內註冊(註冊的範圍根據實際業務需求來)

// 註冊一個全域性指令,可以在任何元件使用
Vue.directive('focus',{
    // 當被繫結的元素插入 DOM 時
    inserted: function(el){
        // 聚焦元素
        el.focus()
    }
})

// 在元件內註冊,只能當前元件使用 directives:{ focus:{ inserted: function(el){ el.focus() } } } // 使用 <input v-focus>

2、鉤子函式

對於一個指令有下面一些鉤子函式可以選擇:

  • bind:只調用一次,指令第一次繫結到元素時呼叫

  • inserted:被繫結元素插入父節點時呼叫

  • update:所在元件的 VNode 更新時呼叫,但是可能發生在其子 VNode 更新之前

  • componentUpdated:指令所在的 VNode 及其子 VNode 全部更新後呼叫

  • unbind:只調用一次,指令與元素解綁時呼叫

3、函式引數

指令鉤子函式會被傳入以下引數:

  • el:指令所繫結的元素,可以用來直接操作 DOM

  • binding:一個物件,包含以下 property:

    • name:指令名

    • value:指令繫結的值

    • oldValue:指令繫結的前一個值

    • expression:字串形式的指令表示式

    • arg:傳給指令的引數

    • modifiers:一個包含修飾符的物件

  • vnode:Vue 編譯生成的虛擬節點

  • oldVnode:上一個虛擬節點

二、拖動實現

拖動的實現:給目標 Element 註冊 mousedown 事件,在這個事件裡面再對 document 的 mousemove 和 mouseup 註冊。

程式碼如下:

  directives: {
    drag: {
      // 拖動標題欄,讓父元素改變位置,這裡所以選擇 inserte的
      inserted: (el) => {
        const target = el.parentElement
        el.onmousedown = (e) => {
          const disX = e.pageX - target.offsetLeft
          const disY = e.pageY - target.offsetTop
          document.onmousemove = (de) => {
            target.style.left = de.pageX - disX + 'px'
            target.style.top = de.pageY - disY + 'px'
          }
          document.onmouseup = (de) => {
            document.onmousemove = document.onmouseup = null
          }
        }
      }
    }
  }

在需要的 Element 上面使用 v-drag 即可。