官方文档传送门
一、什么是draggable,用来干嘛的
Vue.Draggable是一款基于Sortable.js实现的vue拖拽插件。支持移动设备、拖拽和选择文本、智能滚动,可以在不同列表间拖拽、不依赖jQuery为基础、vue 2过渡动画兼容、支持撤销操作,总之是一款非常优秀的vue拖拽组件。本篇将介绍如何搭建环境及简单的例子,使用起来特别简单对被拖拽元素也没有CSS样式的特殊要求。
二、draggable 安装
NPM或yarn安装方式
yarn add vuedraggable
npm i -S vuedraggable
UMD浏览器直接引用JS方式
<script src="http://www.itxst.com/package/vue/vue.min.js"></script>
<script src="http://www.itxst.com/package/sortable/Sortable.min.js"></script>
<script src="http://www.itxst.com/package/vuedraggable/vuedraggable.umd.min.js"></script>
三、在vue中使用
在对应的页面引入draggable组件
import draggable from 'vuedraggable'
四、简单案例
<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 1px #3089dc !important;
}
</style>
<script>
//导入draggable组件
import draggable from 'vuedraggable'
export default {
//注册draggable组件
components: {
draggable,
},
data() {
return {
drag:false,
//定义要被拖拽对象的数组
myArray:[
{people:'cn',id:10,name:'www.itxst.com'},
{people:'cn',id:20,name:'www.baidu.com'},
{people:'cn',id:30,name:'www.taobao.com'},
{people:'us',id:40,name:'www.yahoo.com'}
]
};
},
methods: {
//开始拖拽事件
onStart(){
this.drag=true;
},
//拖拽结束事件
onEnd() {
this.drag=false;
},
},
};
</script>
五、使用中遇到的问题
- 使用 filter 禁止拖拽后,filter禁止标签下的输入框,无法输入
解决办法: 不使用 filter 禁止,改用 draggable (draggable 参数大概意思就是只能拖拽对应的类选择器)
// 大概意思就是标签带 singlePerson class的可以拖动 <draggable ghostClass="ghost" draggable=".singlePerson" :list="list" group="people"></draggable>
- 使用 draggable 后,拖动不到想要的位置,只能默认在数组最后
解决办法:draggable标签 加一个 @end 和 @start 的事件回调,当 start 的时候 在标签加上 singlePerson,当end 的时候在移除<template> <draggable @end="endFn" style="width: 100%; min-height: 80vh;background: #f00" ghostClass="ghost" @end="endFn" @start="startFn" draggable=".singlePerson" :list="organizeDataV2" group="people"> <div :class="{'singlePerson': modularStart}"> </div> </draggable> </template> <script> export default { data () { return { modularStart: false } }, methods: { endFn () { this.modularStart = false }, startFn () { this.modularStart = true } } } </script>
- 修改 draggable 拖拽效果
解决办法: 使用参数 ghostClass 绑定一个 class,如果在自己在写 class 做出改变<template> <draggable ghostClass="ghost" :list="list" group="people"></draggable> </template> <style scoped lang="less" rel="stylesheet/less"> .ghost { width: 100%; height: 70px; text-align: center; background-color: #00f; background-repeat: no-repeat; background-size: cover; color: transparent; } .ghost::after { content: '可将模块放置到此区域'; color: #3089dc; margin-top: 15px; position: relative; top: -20px; height: 40px; line-height: 40px; -webkit-box-sizing: border-box; box-sizing: border-box; padding: 0 20px; background: #e4f0fd; display: inline-block; } </style>
- 使用clone拷贝,拷贝了多个同一个对象,修改其中一个对象,其他拷贝的对象内容也会跟着改变
解决办法: 因为 clone的拷贝是浅拷贝,所以会出现这种情况,所以推荐不使用 draggable 绑定的 list 作为拖拽完成数组
推荐使用方法: draggable 绑定一个 edn(鼠标发下) 回调,回调中有返回 oldIndex(对象在拖动的下标) newIndex (对象在拖动完成,在新数组的下标)
<template> <draggable @end="endFn" ghostClass="ghost" :list="list" group="people"></draggable> </template> methods: { endFn (e) { const oldIndex = e.oldIndex const newIndex = e.newIndex } }
- 使用clone拷贝,拷贝了多个同一个对象,修改其中一个对象,其他拷贝的对象内容也会跟着改变