Bootstrap

vuedraggable在vue2.0和vue3.0 中的应用

vuedraggable

Vue.Draggable是一款基于Sortable.js实现的vue拖拽插件。支持移动设备、拖拽和选择文本、智能滚动,可以在不同列表间拖拽、不依赖jQuery为基础、vue 2过渡动画兼容、支持撤销操作,总之是一款非常优秀的vue拖拽组件。

vuedraggable中文文档
github网站
官网

  1. vuedraggable特性
  • 支持触摸设备
  • 支持拖拽和选择文本
  • 支持智能滚动
  • 支持不同列表之间的拖拽
  • 不以jQuery为基础
  • 和视图模型同步刷新
  • 和vue2的国度动画兼容
  • 支持撤销操作
  • 当需要完全控制时,可以抛出所有变化
  • 可以和现有的UI组件兼容
  1. 安装
      // Vue 2.0: 
      npm install vuedraggable@5
      // Vue 3.0:
      npm install vuedraggable@next
    
  2. UMD浏览器直接引用JS方式
    <script src="https://www.itxst.com/package/vue/vue.min.js"></script>
    <script src="https://www.itxst.com/package/sortable/Sortable.min.js"></script>
    <script src="https://www.itxst.com/package/vuedraggable/vuedraggable.umd.min.js"></script>
    
  3. 组件中的引用
    // Vue 2.0
    import draggable from 'vuedraggable';
     
    export default {
      components: {
        draggable
      },
      // ...
    }
    // Vue 3.0
    import { draggable } from 'vuedraggable';
     
    export default {
      components: {
        draggable
      },
      // ...
    }
    
  4. 属性说明
    如果下面的属性说明未能完全看明白,请访问非vue版 sortable.js 里面有更详细的例子。
    属性名称说明
    group:group= “name”,相同的组之间可以相互拖拽或者 { name: “…”, pull: [true, false, ‘clone’, array , function], put: [true, false, array , function] }
    sort:sort= “true”,是否开启内部排序,如果设置为false,它所在组无法排序,在其他组可以拖动排序
    delay:delay= “0”, 鼠标按下后多久可以拖拽
    touchStartThreshold鼠标移动多少px才能拖动元素
    disabled:disabled= “true”,是否启用拖拽组件
    animation拖动时的动画效果,还是很酷的,数字类型。如设置animation=1000表示1秒过渡动画效果
    handle:handle=“.mover” 只有当鼠标移动到css为mover类的元素上才能拖动
    filter:filter=“.unmover” 设置了unmover样式的元素不允许拖动
    draggable:draggable=“.item” 那些元素是可以被拖动的
    ghostClass:ghostClass=“ghostClass” 设置拖动元素的占位符类名,你的自定义样式可能需要加!important才能生效,并把forceFallback属性设置成true
    chosenClass:ghostClass=“hostClass” 被选中目标的样式,你的自定义样式可能需要加!important才能生效,并把forceFallback属性设置成true
    dragClass:dragClass="dragClass"拖动元素的样式,你的自定义样式可能需要加!important才能生效,并把forceFallback属性设置成true
    dataIdAttrdataIdAttr: ‘data-id’
    forceFallback默认false,忽略HTML5的拖拽行为,因为h5里有个属性也是可以拖动,你要自定义ghostClass chosenClass dragClass样式时,建议forceFallback设置为true
    fallbackClass默认false,克隆的DOM元素的类名
    allbackOnBody默认false,克隆的元素添加到文档的body中
    fallbackTolerance拖拽之前应该移动的px
    scroll默认true,有滚动区域是否允许拖拽
    scrollFn滚动回调函数
    scrollSensitivity距离滚动区域多远时,滚动滚动条
    scrollSpeed滚动速度
    • group属性 拖拽分组多组之间相互拖拽,可以实现不同数组之间相互拖拽。比如group都为itxst的组之间可以相互拖动。
         //设置方式一,直接设置组名
         group:'itxst'
         //设置方式,object,也可以通过自定义函数function实现复杂的逻辑
         group:{
             name:'itxst',//组名为itxst
             pull: true|false| 'clone'|array|function,//是否允许拖出当前组
             put:true|false|array|function,//是否允许拖入当前组
         }
         	```
      
    • delay属性 鼠标按下后等待n秒才允许拖动,此属性可以一定程度上防止误触操作,比如设置delay为1000表示按下一秒后才允许拖动。
    • disabled属性 实现开启或禁用vue.draggable的拖拽效果。
    • scroll属性 容器有滚动条时是否允许滚动及当父容器元素有滚动条时是否允许拖动。
    • animation属性 设置vue.draggable过渡效果,这样拖动时过渡位置就不会显的太生硬, 默认值0。
    • handle属性 当鼠标落在handle指定的元素上面时才允许拖动,如下面的例子只能点击加号区域才能拖动,点击其他区域则无法拖动。
    • filter 如果你想设置某个元素或对象不允许拖动拖拽把这些元素的样式名称设置到filter属性即可,本文将实现包含forbid样式的元素将无法拖动,第一行无法拖动,也无法拖动到第一行,用到filter和move属性。
      <draggable v-model="arr1" 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>
      
    • chosenClass属性 设置选中元素的样式,可以通过自定义样式来方便的区分出那个元素被选中。
    • ghostClass属性 目标位置占位符的样式及需要停靠位置的样式。
    • clone拷贝 实现常用菜单功能,从一个拖拽组拖动到另外一个组而原来的那种组的元素不移除。
  5. 事件说明
    事件名称说明
    start开始拖动时触发的事件
    add从一个数组拖拽到另外一个数组时触发的事件
    remove移除事件
    update拖拽变换位置时触发的事件
    end拖拽完成时的事件
    choose鼠标点击选中要拖拽元素时的事件
    unchoose选中后松开鼠标的事件
    sort位置变化时的事件
    clone从一个数组拖拽到另外一个数组时触发的事件和add不同,clone是复制了数组元素
    move自定义控制那些元素可以拖拽或不允许拖拽,实际业务场景往往会比较复杂,往往在拖拽过程中才能知道那些元素允许停靠,点击时才知道那些元素是否允许拖拽。

在vue2.0中的应用

<template>
  <div>
  <div>{{drag?'拖拽中':'拖拽停止'}}</div>
  <!--使用draggable组件-->
 <draggable v-model="myArray"  chosenClass="chosen" forceFallback="true" group="people" animation="1000" @start="onStart" @end="onEnd">
    <transition-group>
     <div class="item" v-for="element in myArray" :key="element.id">{{element.name}}</div>
    </transition-group>
</draggable> 
  </div>
</template>
<style scoped>
        /*被拖拽对象的样式*/
        .item {
            padding: 6px;
            background-color: #fdfdfd;
            border: solid 1px #eee;
            margin-bottom: 10px;
            cursor: move;
        } 
        /*选中样式*/
        .chosen {
            border: solid 2px #3089dc !important;
        }
</style>
<script>
//导入draggable组件
import draggable from 'vuedraggable'
export default {
  //注册draggable组件
   components: {
            draggable,
        },
   data() {
    return { 
      drag:false,
      //定义要被拖拽对象的数组
      myArray:[
        {people:'cn',id:1,name:'www.itxst.com'},
        {people:'cn',id:2,name:'www.baidu.com'},
        {people:'cn',id:3,name:'www.taobao.com'},
        {people:'us',id:4,name:'www.google.com'}
        ] 
    };
  },
  methods: {
     //开始拖拽事件
      onStart(){
        this.drag=true;
      },
      //拖拽结束事件
       onEnd() {
       this.drag=false;
    },
  },
};
</script>

在vue3.0中的应用

<template>
  <div class="itxst">
    <div>
      <draggable
        :list="state.list"
        ghost-class="ghost"
        chosen-class="chosenClass"
        animation="300"
        @start="onStart"
        @end="onEnd"
      >
        <template #item="{ element }">
          <div class="item">
            {{ element.name }}
          </div>
        </template>
      </draggable>
    </div>
    <div>{{ state.list }}</div>
  </div>
</template>
<script setup>
import { ref, reactive } from "vue";
import draggable from "vuedraggable";
/*
draggable 对CSS样式没有什么要求万物皆可拖拽
:list="state.list"         //需要绑定的数组
ghost-class="ghost"        //被替换元素的样式
chosen-class="chosenClass" //选中元素的样式
animation="300"            //动画效果
@start="onStart"           //拖拽开始的事件
@end="onEnd"               //拖拽结束的事件
*/
const state = reactive({
  //需要拖拽的数据,拖拽后数据的顺序也会变化
  list: [
    { name: "www.itxst.com", id: 0 },
    { name: "www.baidu.com", id: 1 },
    { name: "www.google.com", id: 2 },
  ],
});

//拖拽开始的事件
const onStart = () => {
  console.log("开始拖拽");
};

//拖拽结束的事件
const onEnd = () => {
  console.log("结束拖拽");
};
</script>
<style scoped>
.itxst {
  width: 600px;
  display: flex;
}
.itxst > div:nth-of-type(1) {
  flex: 1;
}
.itxst > div:nth-of-type(2) {
  width: 270px;
  padding-left: 20px;
}
.item {
  border: solid 1px #eee;
  padding: 6px 10px;
  text-align: left;
}

.item:hover {
  cursor: move;
}
.item + .item {
  margin-top: 10px;
}
.ghost {
  border: solid 1px rgb(19, 41, 239);
}
.chosenClass {
  background-color: #f1f1f1;
}
</style>
;