1. 程式人生 > 實用技巧 >vue下使用drag完成簡單拖拽

vue下使用drag完成簡單拖拽

因為沒有時間研究jquery的sortable功能(也沒有文件),所以用HTML5的drag完成了簡單的拖拽,這裡記錄下

`@dragstart` , `@dragover` , `@dragend` , `dragable`

dragable 確認可以被拖拽的元素

<ul @dragstart="onDragStart($event)" 
   @dragover="onDragOver($event)" @dragend="onDragEnd($event)" ref="box"> <li v-for="(item,index) in options" :index="index" class="item" draggable
="true" :value="item.value" :key="item.value" v-show="item._checked"> {{item.label}} </li>
</ul>

script內部程式碼

/**
       * 拖拽開始
       */
      onDragStart(e) {
        boxHeight = Math.floor(e.target.offsetHeight/2)
        this.draging = e.target
      },

/**
       * 拖拽過程
       
*/ onDragOver(e) { // console.log('move', e) this.target = e.target let targetTop = e.target.getBoundingClientRect().top let dragingTop = this.draging.getBoundingClientRect().top // console.log('drag move', targetTop) if(this.target.nodeName==='LI'&&this
.target !== this.draging) { if(this.target&&this.target.animated) { return } let targetIndex = this.target.getAttribute('index') let dragingIndex = this.draging.getAttribute('index') if(targetIndex > dragingIndex) {//拖拽元素往下移動 //target的下一個元素 this.target.parentNode.insertBefore(this.draging, this.target.nextSibling) }else{ this.target.parentNode.insertBefore(this.draging, this.target) } this._animation(targetTop, this.target) this._animation(dragingTop, this.draging) } }, /** * 拖拽結束 */ onDragEnd(e) { var tOptions = JSON.parse(JSON.stringify(this.options)); let currentArray = Array.from(this.$refs['box'].childNodes) let data = currentArray.map((item,i)=>{ let obj = tOptions.find(c=>c.value===item.getAttribute('value')) obj.index = i return obj }) this.options = data this.initOptions() }, /** * 拖拽的動畫過程 */ _animation(clientTop, dom) { let offset = clientTop - dom.getBoundingClientRect().top //元素移動後的新位置 //console.log('target+draging', offset) dom.style.transition = 'none'; dom.style.transform = `translateY(${offset}px)` //觸發重繪 //console.log('offsetWidth:', dom.offsetWidth) //offsetWidth導致了瀏覽器重繪(瞭解瀏覽器重排、重繪) dom.style.transition = 'transform 0.3s'; dom.style.transform = ''; clearTimeout(dom.animated); dom.animated = setTimeout(()=>{ dom.style.transition = '' dom.style.transform = '' dom.animated=false },150) },

這樣簡單的拖拽就完成了,在這裡要著重強調 `v-for` 的情況下,key值很重要,因為key值我給的是index值,發現每次排完序之後都是沒重新排序的樣子,犯了低階錯誤

key 為每個節點提供身份標識,資料改變時會重排,所以最好繫結唯一標識。

注意:如果用index標識可能得不到想要的效果,所以我在專案中使用了每個元素的value來作為 key