Vue实用功能之实现拖拽元素、列表拖拽排序
周围都是小趴菜 人气:9Vue实现拖拽元素、列表拖拽排序
需求:
1、左右两个容器,左边和右边的元素可以拖动互换
2、列表拖拽排序
组件使用
Vue.Draggable是一款基于Sortable.js实现的vue拖拽插件支持移动设备、拖拽和选择文本、智能滚动,可以在不同列表间拖拽、不依赖jQuery为基础,vue2过渡动画兼容、支持撤销操作,总之是一款非常优秀的vue拖拽组件
npm或yarn安装方式
yarn add vuedraggable npm i -S vuedraggable
<template> <div> <!--使用draggable组件--> <div class="itxst"> <div>自定义控制拖拽和停靠</div> <div class="col"> <!-- 左边容器 --> <!-- group: :group= "name",相同的组之间可以相互拖拽或者 { name: "...", pull: [true, false, 'clone', array , function], put: [true, false, array , function] } ghostClass::ghostClass="ghostClass" 设置拖动元素的占位符类名,你的自定义样式可能需要加!important才能生效,并把forceFallback属性设置成true chosenClass :ghostClass="hostClass" 被选中目标的样式,你的自定义样式可能需要加!important才能生效,并把forceFallback属性设置成true filter :filter=".unmover" 设置了unmover样式的元素不允许拖动 --> <draggable v-model="arr1" group="itxst" ghostClass="ghost" chosenClass="chosen" filter=".forbid" animation="300" :move="onMove"> <transition-group> <div :class="item.id==1?'item forbid':'item'" v-for="item in arr1" :key="item.id">{{item.name}}</div> </transition-group> </draggable> </div> <!-- 右边容器 --> <div class="col"> <draggable v-model="arr2" group="itxst" ghostClass="ghost" chosenClass="chosen" filter=".forbid" animation="300" :move="onMove"> <transition-group> <div :class="item.id==1?'item forbid':'item'" v-for="item in arr2" :key="item.id">{{item.name}}</div> </transition-group> </draggable> </div> </div> </div> </template> <script> //导入draggable组件 import draggable from 'vuedraggable' export default { //注册draggable组件 components: { draggable, }, data() { return { //定义要被拖拽对象的数组 arr1: [{ id: 1, name: 'www.itxst.com(不允许停靠)' }, { id: 2, name: 'www.jd.com' }, { id: 3, name: 'www.baidu.com' }, { id: 5, name: 'www.google.com' }, { id: 4, name: 'www.taobao.com(不允许拖拽)' } ], arr2: [{ id: 11, name: '微软' }, { id: 12, name: '亚马逊' }, { id: 13, name: '京东' }, { id: 15, name: '谷歌' }, { id: 14, name: '苹果' } ] }; }, methods: { //move回调方法 onMove(e, originalEvent) { console.log(e) console.log(originalEvent) //不允许停靠 if (e.relatedContext.element.id == 1) return false; //不允许拖拽 if (e.draggedContext.element.id == 4) return false; return true; }, }, }; </script> <style scoped> /*定义要拖拽元素的样式*/ .drag { background-color: blue !important; border: solid 3px red; } .chosen { background-color: #333 !important; color: #fff; } .ghost { background-color: red !important; } .itxst { margin: 10px; text-align: left; } .col { width: 40%; flex: 1; padding: 10px; border: solid 1px #eee; border-radius: 5px; float: left; } .col+.col { margin-left: 10px; } .item { padding: 6px 12px; margin: 0px 10px 0px 10px; border: solid 1px #eee; background-color: #f1f1f1; text-align: left; } .item+.item { border-top: none; margin-top: 6px; } .item:hover { background-color: #fdfdfd; cursor: move; } </style>
补充:排序动画
如果不熟悉Vue的transition-group,请先学习Vue的列表的排序过渡,这里不再赘述。
为了便于和上面的代码进行比较,同样一次性把全部代码贴出,可以看到代码变动并不大,只需把HTML的ul元素改为transition-group,在methods中新增shuffle方法,在CSS中新增一个过渡transition: transform .3s;即可实现开头第一张图所展示的拖拽排序效果了。
<template> <div> <transition-group name="drag" class="list" tag="ul" > <li @dragenter="dragenter($event, index)" @dragover="dragover($event, index)" @dragstart="dragstart(index)" draggable v-for="(item, index) in list" :key="item.label" class="list-item"> {{item.label}} </li> </transition-group> </div> </template> <script> export default { data() { return { list: [ { label: '列表1' }, { label: '列表2' }, { label: '列表3' }, { label: '列表4' }, { label: '列表5' }, { label: '列表6' }, ], dragIndex: '', enterIndex: '', }; }, methods: { shuffle() { this.list = this.$shuffle(this.list); }, dragstart(index) { this.dragIndex = index; }, dragenter(e, index) { e.preventDefault(); // 避免源对象触发自身的dragenter事件 if (this.dragIndex !== index) { const moving = this.list[this.dragIndex]; this.list.splice(this.dragIndex, 1); this.list.splice(index, 0, moving); // 排序变化后目标对象的索引变成源对象的索引 this.dragIndex = index; } }, dragover(e, index) { e.preventDefault(); }, }, }; </script> <style lang="scss" scoped> .list { list-style: none; .drag-move { transition: transform .3s; } .list-item { cursor: move; width: 300px; background: #EA6E59; border-radius: 4px; color: #FFF; margin-bottom: 6px; height: 50px; line-height: 50px; text-align: center; } } </style>
总结
加载全部内容