首页 > 技术文章 > Vue.Draggable (拖拽排序)

suntongxue 2020-07-08 13:45 原文

安装
npm install vuedraggable
1
引入
import draggable from 'vuedraggable'
1
基础用法
定义一个json串 list,实现它的拖拽排序。

<template>
  <div>
    <!-- 调用组件 -->
    <draggable element="ul" v-model="list">
      <li v-for="item in list">{{item.name}}</li>
    </draggable>
    <!-- 输出list数据 -->
    {{list}}
  </div>
</template>

<script>
// 引入拖拽组件
import draggable from 'vuedraggable'
export default {
    name: 'demo',
  components: {
  //调用组件
    draggable,
  },
  data () {
    return {
      list:[
    {
    id: 1,
    name: 'a'
    },
    {
    id: 2,
    name: 'b'
    },
    {
    id: 3,
    name: 'c'
    },
    {
    id: 4,
    name: 'd'
    },
    {
    id: 5,
    name: 'e'
    },
    {
    id: 6,
    name: 'f'
    },
      ]
  }
},
}
</script>


属性
value
Array,非必须,默认为null

用于实现拖拽的list,通常和内部v-for循环的数组为同一数组。
最好使用vuex来实现传入。
不是直接使用,而是通过v-model引入。
<draggable v-model="myArray">
1
list
Array,非必须,默认为null

就是value的替代品。
和v-model不能共用
从表现上没有看出不同
element
String,默认div

就是<draggable>标签在渲染后展现出来的标签类型
也是包含拖动列表和插槽的外部标签
可以用来兼容UI组件
options
Object

配置项
  group: string or array 分组用的,同一组的不同list可以相互拖动
  sort: boolean 定义是否可以拖拽
  delay:number 定义鼠标选中列表单元可以开始拖动的延迟时间
  touchStartThreshold:number (不清楚)
  disabled: boolean 定义是否此sortable对象是否可用,为true时sortable对象不能拖放排序等功能
  store:
  animation: umber 单位:ms 动画时间
  handle: selector 格式为简单css选择器的字符串,使列表单元中符合选择器的元素成为拖动的手柄,只有按住拖动手柄才能使列表单元进行拖动
  filter: selector 格式为简单css选择器的字符串,定义哪些列表单元不能进行拖放,可设置为多个选择器,中间用“,”分隔
  preventOnFilter: 当拖动filter时是否触发event.preventDefault()默认触发
  draggable: selector 格式为简单css选择器的字符串,定义哪些列表单元可以进行拖放
  ghostClass: selector 格式为简单css选择器的字符串,当拖动列表单元时会生成一个副本作为影子单元来模拟被拖动单元排序的情况,此配置项就是来给这个影子单元添加一个class,我们可以通过这种方式来给影子元素进行编辑样式
  chosenClass: selector 格式为简单css选择器的字符串,目标被选中时添加
  dragClass:selector 格式为简单css选择器的字符串,目标拖动过程中添加
  forceFallback: boolean 如果设置为true时,将不使用原生的html5的拖放,可以修改一些拖放中元素的样式等
  fallbackClass: string 当forceFallback设置为true时,拖放过程中鼠标附着单元的样式
  dataIdAttr: data-id
  scroll:boolean当排序的容器是个可滚动的区域,拖放可以引起区域滚动
  scrollFn:function(offsetX, offsetY, originalEvent, touchEvt, hoverTargetEl) { … } 用于自定义滚动条的适配
  scrollSensitivity: number 就是鼠标靠近边缘多远开始滚动默认30
  scrollSpeed: number 滚动速度


函数配置

  setData: 设置值时的回调函数
  onChoose: 选择单元时的回调函数
  onStart: 开始拖动时的回调函数
  onEnd: 拖动结束时的回调函数
  onAdd: 添加单元时的回调函数
  onUpdate: 排序发生变化时的回调函数
  onRemove: 单元被移动到另一个列表时的回调函数
  onFilter: 尝试选择一个被filter过滤的单元的回调函数
  onMove: 移动单元时的回调函数
  onClone: clone时的回调函数
 以上函数对象的属性:
  to: 移动到的列表的容器
  from:来源列表容器
  item: 被移动的单元
  clone: 副本的单元
  oldIndex:移动前的序号
  newIndex:移动后的序号
  clone
  function,默认值: 无处理

这一项要配合着options的group项的pull项处理,当pull:'clone时的拖拽的回调函数’
就是克隆的意思。
可以理解为正常的拖拽变成了复制。
当为true时克隆
move
function,默认值:null

就是拖拽项时调用的函数
用来确定拖拽是否生效
返回null时可以生效
可以通过函数判断
有一个参数:evt
evt为object
draggedContext: 被拖拽元素的上下文
index:拖拽元素的指针
element: 拖拽数据本身
futureIndex: 拖动后的index
relatedContext: 拖入区域的上下文
index: 目标元素的index
element:目标数据本身
list: 拖入的列表
component:目标组件
<draggable element="ul" v-model="list" :move='allow'>
...
methods: {
allow(evt) {
console.log(evt.draggedContext.index)
console.log(evt.draggedContext.element)
console.log(evt.draggedContext.futureIndex)
console.log(evt.relatedContext.index)
console.log(evt.relatedContext.element)
console.log(evt.relatedContext.list)
console.log(evt.relatedContext.component)
return (evt.draggedContext.element.name!== 'b')
}
}

 


componentData
Object,默认值:null

用来结合UI组件的,可以理解为代理了UI组件的定制信息
包含两项:props和on
props用来代理UI组件需要绑定的属性(:)
on用来代理UI组件需要绑定的事件(@)
<draggable element="el-collapse" :list="list" :component-data="getComponentData()">
<el-collapse-item v-for="e in list" :title="e.title" :name="e.name" :key="e.name">
<div>{{e.description}}</div>
</el-collapse-item>
</draggable>
1
2
3
4
5
methods: {
handleChange() {
console.log('changed');
},
inputChanged(value) {
this.activeNames = value;
},
getComponentData() {
return {
on: {
change: this.handleChange,
input: this.inputChanged
},
props: {
value: this.activeNames
}
};
}
}

 

 


事件
有以下几种

start, add, remove, update, end, choose, sort, filter, clone
1
参数带有如下属性:

add: 包含被添加到列表的元素
newIndex: 添加后的新索引
element: 被添加的元素
removed: 从列表中移除的元素
oldIndex: 移除前的索引
element: 被移除的元素
moved:内部移动的
newIndex: 改变后的索引
oldIndex: 改变前的索引
element: 被移动的元素
插槽
提供一个footer插槽,在排序列表之下。
永远位于最下方。

<draggable v-model="myArray" :options="{draggable:'.item'}">
  <div v-for="element in myArray" :key="element.id" class="item">
    {{element.name}}
  </div>
  <button slot="footer" @click="addPeople">Add</button>
</draggable>

推荐阅读