Vue利用draggable实现多选拖拽效果

 更新时间:2022年05月06日 14:48:04   作者:宜简  
这篇文章主要为大家详细介绍了如何利用vue中的draggable插件实现多选拖拽效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

前言

最近产品提出一个排序需求,希望能进行拖拽排序,我一想,vue2插件这么多,sortable.js、draggable分分钟实现了,但是还有一个需求希望能够实现多选拖拽,这个就有点麻烦,查询了许多资料,暂时没有发现能够多选的拖拽组件,如果自己写一个,既耗费时间,实现效果上必然没有draggable这种成熟轮子效果好,于是决定基于draggable做改进。

实现思路

我们知道draggable插件只要设置相同的group名字就能实现分组拖拽,如果我们渲染两个同名分组,控制第二个分组的显示与隐藏,鱼目混珠,就能实现简单的多选拖拽效果

1.通过group="task"设置两个同名分组,同时利用draggable=".card"属性,控制class名称,禁止单选

  <draggable group="task" v-model="dataList" @end="draggerEnd" class=""
        :class="show ? 'order-box-show' : 'order-box'" animation="300" draggable=".card">
        <transition-group>
          <div v-for="(item, index) in dataList" :key="index" class="box" @click="handleSelect(index)"
            :class="item.select || show ? 'card' : ''">{{ item.name }}
          </div>
        </transition-group>
      </draggable>
      <div class="position" v-show="show">
        <draggable group="task" v-model="dataList2" @end="draggerEnd" class="order-box" animation="300">
          <transition-group>
            <div v-for="(item, index) in dataList2" :key="index" class="boxs">
              <div>
                {{ item.name }}
              </div>
            </div>
          </transition-group>
        </draggable>

2.通过v-show="show"控制第二个分组的隐藏与展示,同时对数据做处理,并且在拖拽结束后,要在分组一中找到分组二拖拽过来的初始元素删掉

    const findIndex = this.dataList.findIndex((item => item.name === '选中元素展示区'))
      this.dataList.splice(findIndex, 1)

Demo全部代码

<template>
  <div>
    <div>
      <draggable group="task" v-model="dataList" @end="draggerEnd" class=""
        :class="show ? 'order-box-show' : 'order-box'" animation="300" draggable=".card">
        <transition-group>
          <div v-for="(item, index) in dataList" :key="index" class="box" @click="handleSelect(index)"
            :class="item.select || show ? 'card' : ''">{{ item.name }}
          </div>
        </transition-group>
      </draggable>
      <div class="position" v-show="show">
        <draggable group="task" v-model="dataList2" @end="draggerEnd" class="order-box" animation="300">
          <transition-group>
            <div v-for="(item, index) in dataList2" :key="index" class="boxs">
              <div>
                {{ item.name }}
              </div>
            </div>
          </transition-group>
        </draggable>
      </div>
    </div>
    <el-button style="marginLeft:50px" @click="handleStart">确认</el-button>
  </div>
</template>

<script>
import draggable from 'vuedraggable'
export default {
  components: {
    draggable
  },
  data() {
    return {
      dataList: [
      ],
      dataList2: [{ name: '选中元素展示区' }],
      show: false,
      selectArr: [],
    }
  },
  mounted() {
    for (var i = 0; i < 60; i++) {
      this.dataList.push({ name: i, select: false })
    }
  },
  methods: {
    handleSelect(index) {
      const data = JSON.parse(JSON.stringify(this.dataList))
      data[index].select = true
      this.selectArr.push({ ...data[index] })
      this.dataList = JSON.parse(JSON.stringify(data))
    },
    handleStart(e) {
      if (!this.selectArr.length) {
        return
      }
      this.show = true
      this.selectArr.forEach((item, index) => {
        const Index = this.dataList.findIndex(it => item.name === it.name)
        this.dataList.splice(Index, 1)
      })
    },
    draggerEnd(e) {
      const newIndex = e.newIndex
      this.dataList.splice(newIndex, 0, ...this.selectArr)
      const findIndex = this.dataList.findIndex((item => item.name === '选中元素展示区'))
      this.dataList.splice(findIndex, 1)
      this.show = false
    },


  }
}
</script>

<style lang="scss" scoped>
.order-box {
  padding: 20px 50px;
  display: flex;
  flex-wrap: wrap;

  >span {
    flex: 1;
    display: flex;
    flex-wrap: wrap;
  }

  .box {
    width: 100px;
    height: 50px;
    background: rgb(7, 174, 215);
    margin-right: 10px;
    margin-bottom: 10px;
  }

  .boxs {
    width: 100px;
    height: 50px;
    background: rgb(215, 177, 7);
    margin-right: 10px;
    margin-bottom: 10px;
  }

  .card {
    background: rgb(128, 68, 0) !important;
  }
}

.order-box-show {
  padding: 20px 50px;
  display: flex;
  flex-wrap: wrap;

  >span {
    flex: 1;
    display: flex;
    flex-wrap: wrap;
  }

  .box {
    width: 100px;
    height: 50px;
    background: rgb(7, 174, 215);
    margin-right: 10px;
    margin-bottom: 10px;
  }

  .boxs {
    width: 100px;
    height: 50px;
    background: rgb(215, 177, 7);
    margin-right: 10px;
    margin-bottom: 10px;
  }
}

.position {
  border: 1px solid red;
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  cursor: pointer;
}
</style>

Demo实现效果

到此这篇关于Vue利用draggable实现多选拖拽效果的文章就介绍到这了,更多相关Vue draggable多选拖拽内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • vue3 获取元素高度不准的问题

    vue3 获取元素高度不准的问题

    这篇文章主要介绍了vue3 获取元素高度不准的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • VUE mixin 使用示例详解

    VUE mixin 使用示例详解

    混入mixin提供了一种非常灵活的方式,来分发Vue组件中的可复用功能,一个混入对象可以包含任意组件选项,接下来通过本文给大家介绍VUE mixin 使用,需要的朋友可以参考下
    2022-08-08
  • vue左右侧联动滚动的实现代码

    vue左右侧联动滚动的实现代码

    这篇文章主要介绍了vue左右侧联动滚动的实现代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • Vue框架之goods组件开发详解

    Vue框架之goods组件开发详解

    这篇文章主要介绍了Vue框架之goodvs组件开发详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-01-01
  • Vue实现购物车实例代码两则

    Vue实现购物车实例代码两则

    这篇文章主要介绍了Vue实现购物车实例代码,需要的朋友可以参考下
    2020-05-05
  • Vue.js中该如何自己维护路由跳转记录

    Vue.js中该如何自己维护路由跳转记录

    这篇文章主要给大家介绍了关于Vue.js中该如何自己维护路由跳转记录的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Vue.js具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-05-05
  • Vue实现6位数密码效果

    Vue实现6位数密码效果

    这篇文章主要为大家详细介绍了Vue实现6位数密码,优化iOS WebView卡顿,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-08-08
  • vue-cli整合vuex的时候,修改actions和mutations,实现热部署的方法

    vue-cli整合vuex的时候,修改actions和mutations,实现热部署的方法

    今天小编就为大家分享一篇vue-cli整合vuex的时候,修改actions和mutations,实现热部署的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09
  • Vite结合Vue删除指定环境的console.log问题

    Vite结合Vue删除指定环境的console.log问题

    这篇文章主要介绍了Vite结合Vue删除指定环境的console.log问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-03-03
  • Vue eventBus事件总线封装后再用的方式

    Vue eventBus事件总线封装后再用的方式

    EventBus称为事件总线,当两个组件属于不同的两个组件分支,或者两个组件没有任何联系的时候,不想使用Vuex这样的库来进行数据通信,就可以通过事件总线来进行通信,这篇文章主要给大家介绍了关于Vue eventBus事件总线封装后再用的相关资料,需要的朋友可以参考下
    2022-06-06

最新评论