Vue 实现选中、拖拽、排序效果,基于 vuedraggable 实现

今天有个朋友说要作个效果:Vue实现拖拽排序,要有 checked,输出结果是排序后的,要全选,未选中的不能拖动html

其实我以前基于 Sortable 作过一个相似的效果。也给他看过了,没看太明白,他就本身基于 vuedraggable 实现了一下。前端

正好有点问题给他解决了一下。废话很少说,先上最终效果:Vue 拖拽排序效果 测试地址。下面就是最终效果图。vue

image.png

效果一:实现选中 和 全选效果

就下面这样,elementUI 官方 Demo。很简单毫无挑战呀。git

<el-checkbox
    :indeterminate="isIndeterminate"
    v-model="checkAll"
    @change="handleCheckAllChange"
  >所有</el-checkbox
>
<el-checkbox-group
    v-model="checkedCities"
    @change="handleCheckedCitiesChange"
>
    <el-checkbox :class="{'item': checkedCities.find(v=>v==city)}" v-for="city in cities" :label="city" :key="city">{{ city }}</el-checkbox>
</el-checkbox-group>

效果二:实现拖拽效果

拖拽效果基于 vuedraggable 实现。github

问题

这里我凭借个人资深经(踩)验(坑),先提出几个可能存在的问题。微信

  1. <el-checkbox-group v-model="checkedCities"> 实现的效果只是记录选中的项,无排序
  2. vue 和 jQuery 作起来最大的区别是什么?基于以下描述,会出现视图显示和数据对不上。函数

    • vue 经过数据驱动视图,也能够理解为数据改变,视图自动改变。
    • jQuery 经过改变直接视图先反馈数据。
    • 基于上面两点,就能够看到基本上操做 DOM 的库,Vue 在使用的时候都有问题。由于他们只操做了 DOM,而 Vue 须要是的你修改数据

解决方案 & 代码

  1. <el-checkbox-group v-model="checkedCities"> 的问题比较好解决。咱们在数据的时候根据数据源排序一把就 ok。
  2. 由于问题是库只修改 DOM,未修改数据,那么咱们能够考虑监听他的回调事件,而后手动的去修改数据(Sortable 我就这样作的)。
    Vue.Draggable 的封装仍是有点东西的,他提供了 :list="cities" 让你传入数据源,而后操做的时候替你修改数据。
<el-checkbox
    :indeterminate="isIndeterminate"
    v-model="checkAll"
    @change="handleCheckAllChange"
>所有</el-checkbox>
<el-checkbox-group
    v-model="checkedCities"
    @change="handleCheckedCitiesChange">
  <draggable  draggable=".item" :list="cities">
    <el-checkbox :class="{'item': checkedCities.find(v=>v==city)}" v-for="city in cities" :label="city" :key="city">{{ city }}</el-checkbox>
  </draggable>
</el-checkbox-group>

效果三:只有选中的才能拖拽

上面咱们已经实现了拖拽。可是未选中也能拖拽排序就感受怪怪的。
这里有两个作法测试

  1. 我是记得有提供这样的功能,找了找文档果真有 draggable=".item" ,指定可拖拽元素的 class。
    可是它这个效果很诡异,未选中的的确不能拖动了,可是你也不能拖动已选中的占据他的位置。
    因此我又加了个处理。我对数据源作了排序,这样选中和未选中就分堆了。
  2. 接下来讲第二种方案。那就是在他提供的钩子函数上去本身判断当前 DOM 该不应执行拖拽。

总结

  1. Vue 的库在使用中要注意操做元数据,而不是只修改 DOM。

微信公众号:前端linong

欢迎你们关注个人公众号。有疑问也能够加个人微信前端交流群。
clipboard.pngspa