Vue.Draggable

开源项目地址:https://github.com/SortableJS/Vue.Draggable

特征

  • 全面支持Sortable.js功能:
    • 支持触摸设备
    • 支持拖动手柄和可选文本
    • 智能自动滚动
    • 支持不同列表之间的拖放
    • 没有jQuery依赖
  • 保持同步HTML并查看模型列表
  • 与Vue.js 2.0过渡组兼容
  • 取消支援
  • 需要完全控制的事件报告任何更改
  • 重用现有的UI库组件(例如vuetify,element或vue材质等),并使用tag和componentData道具使其可拖动

    效果

    Vue 拖拽组件和功能 - 图1

    Vue页面引用

    1. import draggable from 'vuedraggable'
    2. ...
    3. export default {
    4. components: {
    5. draggable,
    6. }
    7. ...
    8. }
    1. <draggable v-model="myArray" group="people" @start="drag=true" @end="drag=false">
    2. <div v-for="element in myArray" :key="element.id">{{element.name}}</div>
    3. </draggable>

    可拖动组件应直接包装可拖动元素,或 transition-component 包含可拖动元素的。

    1. <draggable v-model="myArray">
    2. <transition-group>
    3. <div v-for="element in myArray" :key="element.id">
    4. {{element.name}}
    5. </div>
    6. </transition-group>
    7. </draggable>

    H5的拖拽功能

    为了让 DOM 元素可以拖拽,我们需要为元素增加 draggable=”true”

    拖拽事件

  • @dragstart :拖拽开始事件,可绑定于被拖拽元素上;

  • @dragend :拖拽结束事件,可绑定于被拖拽元素上;
  • @dragover :拖拽持续移动事件,建议绑定于可拖放区域(下方灰色块);
  • @dragenter :进入拖放区域,建议绑定于可拖放区域(下方灰色块),该事件仅在进入拖放区域时触发,在其内部移动时不触发,离开某一可拖放区域后再进入时会再次触发;

    ondrop事件

    拖放事件,绑定于可拖放DOM 元素上。
    需要注意的是:

    如果DOM元素单独绑定 ondrop 事件,将无法真正地触发它。

  1. <div @drop="drop">...</div>
  2. <script>
  3. drop (event) {
  4. console.log('drop', event)
  5. }
  6. </script>

原因详见MDN ,大概意思是页面DOM元素默认是不许放置的,它通过 ondragover 事件来处理,所以我们需要在 preventDefault() 方法将表明在该位置允许放置。
正常html下的使用

  1. <div ondragover="event.preventDefault()">

Vue文件下,drop和dragover事件的使用

  1. <div @drop="drop" @dragover="dragover"> ...</div>
  2. <script>
  3. methods: {
  4. drop (event) {
  5. console.log('drop', event)
  6. },
  7. dragover (event) {
  8. event.preventDefault()
  9. }
  10. }
  11. </script>

更简洁的写法:

  1. <div @drop="drop" @dragover.prevent> ...</div>
  2. <script>
  3. methods: {
  4. drop (event) {
  5. console.log('drop', event)
  6. }
  7. }
  8. </script>

拖拽对象和拖放区域的消息传递

这里要实现的是不同组件之间的拖拽事件的信息通信,所以使用了 dataTransfer 来进行事件之间的数据传递。

拖拽对象

  1. <div draggable="true" @dragstart="dragstart" @dragend="dragend" v-for="(menu, index) in menus" :key="index">
  2. {{ menu.name }}
  3. </div>
  4. <script>
  5. dragstart(event) {
  6. event.dataTransfer.setData('draginfo', 'hello')
  7. }
  8. dragend (event) {
  9. event.dataTransfer.clearData()
  10. }
  11. </script>

拖放区域

  1. <div @drop="drop" @dragover.prevent >...</div>
  2. <script>
  3. drop (event) {
  4. console.log(event.dataTransfer.getData('draginfo'))
  5. }
  6. </script>

注意事项

  1. 整个拖拽过程的事件执行过程 dragstart=>>drop=>>dragend
  2. dataTransfer 中设置的消息( 即 setData 的第二个参数 )只能是字符串类型。如果想要传递对象,需要先进行序列化。
  3. 不能在被拖拽对象的 dragend 事件中传递消息
  4. 不能在被拖拽对象的 dragover 事件中传递消息

参考