记录Vue.Draggable拖拽组件的使用历程

56 篇文章 4 订阅

项目开发中需要用到 拖拽组件,因为 前端技术框架 是 Vue2

这里就使用了 Vue 的一款 拖拽插件 vue.draggable

一般基本的需求都能满足 ,这里使用了多个 draggable 嵌套,达到两级之间相互拖拽的功能。

以下是类似 teambition 的效果图片,最外层为一个 draggable ,可以左右拖动,

然后每个块里面还有小块,小块组成一个 draggable ,

可以上下拖动,也可以在大的块之间拖动。 

这里说一下实现原理。

首先,要搞清楚 draggable 的 Api ,

Vue.Draggable 是一款基于 Sortable.js 实现的 Vue 拖拽插件

支持 移动设备、拖拽 和 选择文本、智能滚动 ,

可以在 不同列表间 拖拽、不依赖 jQuery 为基础、Vue2 过渡动画兼容、支持撤销操作 ,

使用起来特别简单,对被拖拽元素也没有 CSS 样式的特殊要求。

中文文档 :

vue.draggable中文文档 - itxst.com

里面 基本属性 和 方法都有讲到 ,有时间的可以去学习一下,

要查看详细的说明可以去 git 看官方文档说明,

官方文档 :

GitHub - SortableJS/Vue.Draggable: Vue drag-and-drop component based on Sortable.js

这里用到了以下几个属性和事件,着重说明下:

1、group拖拽分组 ,多组之间相互拖拽 ,可以实现不同数组之间相互拖拽

比如 group 都为 itxst 的组之间才可以相互拖动,

本文例子中分别给两个 draggable 设置了不同的 group 属性,是防止大的被拖到小的块里面去

示例 :group="viewer"  或  group : { name: "viewer", pull: "clone", put: false } 

2、sort : 是否开启内部排序( true / false )

3、disable : 通过 disabled 属性实现 开启 或 禁用 vue.draggable 的 拖拽效果

4、animation :通过 animation 属性设置 vue.draggable 过渡效果

这样拖动时 过渡位置 就不会显的太生硬 。

5、handle : 设置(限制)可拖拽区域

6、ghostClass :目标位置占位符的样式及需要停靠位置的样式

7、chosenClass :被选中目标的样式

8、dragClass :拖动元素的样式

9、list :作为 值属性 的 替代 ,list 是一个与 拖放 同步 的 数组

( 比如说, :list = "data" , 就是说,拖拽组件里面的内容数据绑定了 这个 data 值,

一开始这个 data 可能为 [ ] 空数组,但后续通过绑定 @add="addCommand" ,

即可通过拖拽生成事件来将所拖拽内容本身的数据内容添加至 data 数组中去了,

也就是通过拖拽新生成的数据内容会实时更新至 data 里面了,因此 data 也就有了数据 。)

这里在 二级 draggable 使用了该属性 ,因为 两个 draggable 用到了同一数据源 ,

二级 draggable 中用 list 替代 v-model

10、move : 自定义控制那些元素可以拖拽或不允许拖拽并控制是否允许停靠

11、start() : 开始拖动时触发的事件

12、add() :从一个数组拖拽到另外一个数组时触发的事件

11、end() :拖拽完成时的事件

如果想和后端实现动态更新,可以在这个方法里面和后端进行数据交互

tag : 自定义 导航编译生成后的 HTML 标签


然后就是示例 demo 了,这里一些代码段,样式什么的大家可以自由发挥

1、第一步 ,安装 vue.draggable 插件,yarn 或者 npm 都可以
yarn add vuedraggable
npm i -S vuedraggable

"vuedraggable": "^2.43.3"
2、第二步 ,使用插件
import draggable from 'vuedraggable'

3、注册组件

components: { draggable }

<script>
import draggable from "vuedraggable";

export default {
  components: { draggable },
  data() {
    return {
      disabled: false,
      // 定义要被拖拽对象的数组
      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(不允许拖拽)" },
      ],
    };
  },
  methods: {
    // move回调方法
    moveCommand(e) {
      // 目标是容器不允许停靠
      if (
        e.relatedContext.element &&
        e.relatedContext.element.type === "container"
      )
        return false;
      // 布局容器不允许容器拖拽
      if (
        e.relatedContext.element &&
        e.draggedContext.element.type === "container"
      )
        return false;
      return true;
    },
    // 开始拖动时触发的事件
    startCommand(e) {
      console.log("移动中...", e);
    },
    // 从一个数组拖拽到另外一个数组时触发的事件
    addCommand(e) {},
    // 拖拽完成时的事件
    endCommand(e) {
      console.log("结束移动...", e);
    },
  },
};
</script>

<div>
  <draggable class="list-group" group="task" v-model="projectList" @end="draggerEnd()">
	<div class="card-list-span" v-for="(process, index) in projectList" :key="process.opListId">
	  <div class="span-header">
		<div class="header-title">
		  {{ process.opListName }}
		</div>
	  </div>
	  <div class="span-body">
		<div class="body-list">
		  <draggable
			group="project"
			:list="process.taskVoList"
			@end="taskDraggerEnd()"
		  >
			<div
			  class="body-list-span"
			  v-for="task in process.taskVoList"
			  :key="task.opTaskId"
			>
			  <div>
				{{ task.opTaskTitle }}
			  </div>
			  <div>{{ task.opTaskHandler }}</div>
			</div>
		  </draggable>
		  <div slot="footer">
			<Author author="yunygl-yylcgl-cjrw">
			  <div class="add-task" @click="addTask(index)">
				<i class="el-icon-plus" style="margin-right: 5px;"></i>
				添加任务
			  </div>
			</Author>
		  </div>
		</div>
	  </div>
	</div>
  </draggable>
</div>
 
data() {
 return {
	projectList: [
	{
	id: "001",
	name: "流程一",
	taskList: [
	  {id: "001001",taskTitle: "任务一"},
	  {id: "001002",taskTitle: "任务二"}
	  ]
   },
   {
	id: "002",
	name: "流程二",
	taskList: [
	  {id: "002001",taskTitle: "任务一"}
	  ]
   }
 ]
}
 
method: {
    // 添加任务
    addTask(index) {
      this.projectList[index].taskList.push( {id: "00200232",taskTitle: "任务二"})
    },
}

项目使用 :

  • 4
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值