vue.js封裝多列布局拖拽(grid布局)

先看效果

多列布局拖拽

組件有替換重排兩種方式,默認(rèn)是重排方式,類似于手機九宮格的重排。
組件主要實現(xiàn)思路:計算出每個可拖拽組件的可移動范圍,移動之后計算出目標(biāo)位置的index,如果方式為重排,重新排列數(shù)組順序;如果為替換,則直接替換數(shù)組中拖拽組件原始位置,以及最終位置的兩個數(shù)據(jù)
使用方式比較簡單,給出展示數(shù)據(jù)以及列數(shù)即可,如下:

<template>
  <uni-drag-group :column="3" :drag-data-list.sync="dragDataList" @drag-start="dragStart" @drag-end="dragEnd">
    <template v-slot:default="dragData"><div class="drag-data-div" >這是{{ dragData.data }}數(shù)據(jù)</div></template>
  </uni-drag-group>
</template>
<script>
export default {
  data: function() {
    return {
      dragDataList: ['1', '2', '3', '4', '5', '6']
    }
  },
  methods: {
    dragStart: function(event) {
      this.$message({
        type: 'info',
        message: `拖拽開始,通過console可以查看event參數(shù), ${JSON.stringify(event)}`
      })
      console.info('拖拽開始', event)
    },
    dragEnd: function(event, dragList) {
      this.$message({
        type: 'info',
        message: `拖拽結(jié)束,通過console可以查看event參數(shù), ${JSON.stringify(event)}, ${dragList}`
      })
      console.info('拖拽結(jié)束', event, dragList)
    }
  }
}
</script>
<style scoped>
.drag-data-div {
  background-color: green;
  color: #FFFFFF;
  width: 100px;
  height: 100px;
  line-height: 100px;
}
</style>

下面給出主要計算拖拽組件可移動范圍的代碼:完整代碼請戳這里:傳送門

// 計算當(dāng)前元素可移動的區(qū)域
  getRangeOfEl: function(moveEl) {
      const index = parseInt(moveEl.style.gridArea.split(' / ')[0].split('-')[1])
      const res = {}
      const currentColummn = index % this.column
      res.minX = -((moveEl.offsetWidth + 5) * currentColummn)
      res.maxX = (this.column - currentColummn - 1) * (moveEl.offsetWidth + 5)
      const allRow = Math.ceil(this.dragList.length / this.column)
      const currentRow = Math.floor(index / this.column)
      res.minY = -((moveEl.offsetHeight + 5) * currentRow)
      res.maxY = (allRow - currentRow - 1) * (moveEl.offsetHeight + 5)
      return res
  },
// 計算最終目標(biāo)位置的index值
getIndexOfMoveEL: function(moveEl) {
      const x = parseInt(moveEl.style.left.split('px')[0])
      const y = parseInt(moveEl.style.top.split('px')[0])
      const index = parseInt(moveEl.style.gridArea.split(' / ')[0].split('-')[1])
      let nowIndex = 0
      if (x < 0) {
        nowIndex = index - (Math.round(Math.abs(x) / moveEl.offsetWidth))
      } else {
        nowIndex = index + (Math.round(Math.abs(x) / moveEl.offsetWidth))
      }
      if (y < 0) {
        nowIndex = nowIndex - (Math.round(Math.abs(y) / moveEl.offsetHeight)) * this.column
      } else {
        nowIndex = nowIndex + (Math.round(Math.abs(y) / moveEl.offsetHeight)) * this.column
      }
      return { nowIndex, index }
  },
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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

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