安装拖拽插件
vue3需下载…@next此版本,否则会出现错误

npm i -S vuedraggable@next
npm install sortablejs --save //拖拽组件依赖sortablejs

npm install jsplumb --save

拖拽插件vuedraggable

vue2.x版本Draggable 组件中的配置项写法(:options=“draggableOptions”)在vue3中不起效,

vue3中需要将里面的参数单独进行配置,如 :force-fallback=“true” :group=“{name: ‘article’,pull:‘clone’}” :sort=‘false’ 等

vue2.x使用
<div class="flow-menu" ref="tool">
        <div v-for="menu in menuList" :key="menu.id">
            <span class="ef-node-pmenu" @click="menu.open = !menu.open">
               <i :class="{ 'el-icon-caret-bottom': menu.open, 'el-icon-caret-right': !menu.open }"></i>&nbsp;{{ menu.name }}</span>
          	<ul v-show="menu.open" class="ef-node-menu-ul">
              <draggable  @end="end" @start="move" v-model="menu.children" :options="draggableOptions">
                    <li v-for="subMenu in menu.children"
                        class="ef-node-menu-li"
                        :key="subMenu.id"
                        :type="subMenu.type">
                        {{ subMenu.name }}
                    </li>
             </draggable>
           </ul>
      </div>
</div>

import draggable from 'vuedraggable'
 
export default {
  components: {
    draggable
  },
  data () {
    return {
    //数据
    NodeLeftData: [
			{
				id: 'P301',
				type: 'P331',
				name: '实测',
				open: true,
				children: [
					{
						id: '11',
						type: '11',
						name: '实测子项1',
						state: 'Y',
						ico: 'el-icon-user-solid',
						scantype: 'NORM',
					},
					{
						id: '13',
						type: '13',
						name: '实测子项2',
						state: 'Y',
						ico: 'el-icon-user-solid',
						scantype: 'NORM',
					},
				],
			}
		],
		//配置项
      draggableOptions: {
         preventOnFilter: false,
          sort: false,
          disabled: false,
          ghostClass: "",
          // 不使用H5原生的配置
          forceFallback: true
          // 拖拽的时候样式
          // fallbackClass: 'flow-node-draggable'
      },
    }
  }
vue3.x

数据与上面一致

注意配置项的使用,vue3的配置项与vue2.x的配置项使用有区别
在此停留了许久才找出问题
(force-fallback 属性,可做元素拖拽过程的效果)

<div class="flow-menu" ref="tool">
		<div v-for="menu in menuList" :key="menu.id">
			<span class="ef-node-pmenu" @click="menu.open = !menu.open">
				<SvgIcon :name="menu.open ? 'ele-CaretBottom' : 'ele-CaretRight'" />
				&nbsp;{{ menu.name }}
			</span>
			<ul v-show="menu.open" class="ef-node-menu-ul">
				<!-- vue3中需要将里面的参数单独进行配置,如::group="{name: 'article',pull:'clone'}"     :sort='false'  等
						force-fallback:  忽略HTML5的DnD行为,并强制退出。(h5里有个属性也是拖动,这里是为了去掉H5拖动对这个的影响, 也是用于拖动效果的实现
				 -->
				<Draggable v-model="menu.children" :force-fallback="true" :sort="false"  @end="end" @start="move">
				//template模板的使用也与vue2有所不同
					<template #item="{ element }" :item-key="element.id" :type="element.type">
						<li class="ef-node-menu-li">
							{{ element.name }}
						</li>
					</template>
				</Draggable>
			</ul>
		</div>
	</div>

vuedraggable部分参数
  1. group: “name”, // or { name: “…”, pull: [true, false, clone], put: [true, false, array] } name相同的组可以互相拖动
  2. sort: true, // 内部排序列表
  3. delay: 0, // 以毫秒为单位定义排序何时开始。
  4. touchStartThreshold: 0, // px,在取消延迟拖动事件之前,点应该移动多少像素?
  5. disabled: false, // 如果设置为真,则禁用sortable。
  6. store: null, // @see Store
  7. animation: 150, // ms, 动画速度运动项目排序时,’ 0 ’ -没有动画。
  8. handle: “.my-handle”, // 在列表项中拖动句柄选择器。
  9. filter: “.ignore-elements”, // 不导致拖拽的选择器(字符串或函数)
  10. preventOnFilter: true, // 调用“event.preventDefault()”时触发“filter”
  11. draggable: “.item”, // 指定元素中的哪些项应该是可拖动的。
  12. ghostClass: “sortable-ghost”, // 设置拖动元素的class的占位符的类名。
  13. chosenClass: “sortable-chosen”, // 设置被选中的元素的class
  14. dragClass: “sortable-drag”, //拖动元素的class。
  15. dataIdAttr: ‘data-id’,
  16. forceFallback: false, // 忽略HTML5的DnD行为,并强制退出。(h5里有个属性也是拖动,这里是为了去掉H5拖动对这个的影响
  17. fallbackClass: “sortable-fallback”, // 使用forceFallback时克隆的DOM元素的类名。
  18. fallbackOnBody: false, // 将克隆的DOM元素添加到文档的主体中。(默认放在被拖动元素的同级)
  19. fallbackTolerance: 0, // 用像素指定鼠标在被视为拖拽之前应该移动的距离。
  20. scroll: true, // or HTMLElement
  21. scrollFn: function(offsetX, offsetY, originalEvent, touchEvt, hoverTargetEl) { … }
  22. scrollSensitivity: 30, // px, how near the mouse must be to an edge to start scrolling.
  23. scrollSpeed: 10, // px

Jsplumb 点击跳转官方中文文档

另一个文档: 点击

  1. 引用jsplumb
import { jsPlumb } from 'jsplumb';
  1. 创建实例
state.JsPlumb = jsPlumb.getInstance();
  1. 初始化
state.JsPlumb.ready(() => {
	// 导入默认配置
	state.JsPlumb.importDefaults(jsplumbDefaults);
	// 会使整个jsPlumb立即重绘。
	state.JsPlumb.setSuspendDrawing(false, true);
	后续连线的事件.....
	//setContainer指定作为jsPlumb添加元素的容器(设置拖动范围)
	state.JsPlumb.setContainer(proxy.$refs.efContainer);
}

具体使用可参考 easy-flow开源项目: https://gitee.com/xiaoka2017/easy-flow

最后配上一些配置参数
// jsplumb 默认配置
export const jsplumbDefaults = {
	// 多个锚点 [源锚点,目标锚点]
	Anchors: [
		'Top',
		'TopCenter',
		'TopRight',
		'TopLeft',
		'Right',
		'RightMiddle',
		'Bottom',
		'BottomCenter',
		'BottomRight',
		'BottomLeft',
		'Left',
		'LeftMiddle',
	],
	// 连线的容器id
	Container: 'efContainer', //------'workflow-right',
	// 设置链接线的形状,如直线或者曲线之类的。anchor可以去设置锚点的位置。可选值"<Bezier|Flowchart|StateMachine|Straight>"
	Connector: ['Bezier', { curviness: 100 }],
	// 节点是否可以用鼠标拖动使其断开,默认为true。即用鼠标链接上的连线,也可以使用鼠标拖动让其断开。设置成false,可以让其拖动也不会自动断开
	ConnectionsDetachable: false,
	// 删除线的时候节点不删除
	DeleteEndpointsOnDetach: false,
	//  每当添加或以其他方式创建 Endpoint 并且 jsPlumb 尚未给出任何明确的 Endpoint 定义时将使用
	Endpoint: ['Blank', { Overlays: '' }],
	// 连接中源和目标端点的默认外观
	EndpointStyle: { fill: '#1879ffa1', outlineWidth: 1 },
	// jsPlumb 的内部日志记录是否打开
	LogEnabled: true,
	// 连接器的默认外观
	PaintStyle: {
		stroke: '#E0E3E7',
		strokeWidth: 1,
		outlineStroke: 'transparent',
		outlineWidth: 10,
	},
	// 用于配置任何可拖动元素的默认选项jsPlumb.draggable
	DragOptions: { cursor: 'pointer', zIndex: 2000 },
	// 添加到连接器和端点的默认叠加层。已弃用:从 4.x 开始,将不支持此功能。并非所有叠加层都可以连接到连接器和端点。
	Overlays: [
		[
			// 箭头叠加
			'Arrow',
			{
				width: 10, // 箭头尾部的宽度
				length: 8, // 从箭头的尾部到头部的距离
				location: 1, // 位置,建议使用0~1之间
				direction: 1, // 方向,默认值为1(表示向前),可选-1(表示向后)
				foldback: 0.623, // 折回,也就是尾翼的角度,默认0.623,当为1时,为正三角
			},
		],
		[
			'Label',
			{
				label: '',
				location: 0.5,
				cssClass: 'aLabel',
			},
		],
	],
	// 默认渲染模式 svg、canvas
	RenderMode: 'svg',
	// 悬停状态下连接的默认外观
	HoverPaintStyle: { stroke: '#b0b2b5', strokeWidth: 1 },
	// 悬停状态下端点的默认外观
	EndpointHoverStyle: { fill: 'red' },
	// 端点和连接的默认范围。范围提供了对哪些端点可以连接到哪些其他端点的基本控制
	Scope: 'jsPlumb_DefaultScope',
};
//连线参数
export const jsplumbConnect = {
	isSource: true,
	isTarget: true,
	// 动态锚点、提供了4个方向 Continuous、AutoDefault
	anchor: 'Continuous',
	// 设置连线上面的label样式
	labelStyle: {
		cssClass: 'flowLabel',
	},
	// 修改了jsplumb 源码,支持label 为空传入自定义style(若是自动填充label值,则不需改动源码)
	emptyLabelStyle: {
		cssClass: 'emptyFlowLabel',
	},
};

// 整个节点作为source或者target
export const jsplumbMakeSource = {
	// 设置可以拖拽的类名,只要鼠标移动到该类名上的DOM,就可以拖拽连线
	filter: '.node_Drag',
	filterExclude: false,
	anchor: 'Continuous',
	// 是否允许自己连接自己
	allowLoopback: true,
	maxConnections: -1,
};

// 整个节点作为source或者target
export const jsplumbMakeMakeTarget = {
	filter: '.node_Drag',
	filterExclude: false,
	// 是否允许自己连接自己
	anchor: 'Continuous',
	allowLoopback: true,
	dropOptions: { hoverClass: 'ef-drop-hover' },
};

最后

// 设置连线条件(若是自动填充label值,则不需改动源码)
// 設置label樣式,部分代码
nextTick(() => {
	conn.addClass('flowLabel');
});
Logo

前往低代码交流专区

更多推荐