diff --git a/packages/devui-vue/devui/dragdrop/__tests__/dragdrop.spec.ts b/packages/devui-vue/devui/dragdrop/__tests__/dragdrop.spec.ts
new file mode 100644
index 0000000000000000000000000000000000000000..83981b23ee863aa104b0aed97cadfa21a4e99533
--- /dev/null
+++ b/packages/devui-vue/devui/dragdrop/__tests__/dragdrop.spec.ts
@@ -0,0 +1,8 @@
+import { mount } from '@vue/test-utils';
+import { DragdropDirective } from '../index';
+
+describe('dragdrop test', () => {
+ it('dragdrop init render', async () => {
+ // todo
+ })
+})
diff --git a/packages/devui-vue/devui/dragdrop/index.ts b/packages/devui-vue/devui/dragdrop/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6ab571518cb6e0f43c4eb096d632cc91a9b6c1b4
--- /dev/null
+++ b/packages/devui-vue/devui/dragdrop/index.ts
@@ -0,0 +1,15 @@
+import type { App } from 'vue'
+import DraggableDirective from './src/draggable.directive'
+import DroppableDirective from './src/droppable.directive'
+
+export { DraggableDirective, DroppableDirective }
+
+export default {
+ title: 'Dragdrop 拖拽',
+ category: '通用',
+ status: '10%',
+ install(app: App): void {
+ app.directive('DDraggable', DraggableDirective)
+ app.directive('DDroppable', DroppableDirective)
+ }
+}
diff --git a/packages/devui-vue/devui/dragdrop/src/draggable.directive.ts b/packages/devui-vue/devui/dragdrop/src/draggable.directive.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c53e3342c1f70652f065ff235c678f4ab69d9122
--- /dev/null
+++ b/packages/devui-vue/devui/dragdrop/src/draggable.directive.ts
@@ -0,0 +1,11 @@
+export default {
+ mounted(el: HTMLElement): void {
+ el.setAttribute('draggable', 'true')
+ el.style.cursor = 'grab'
+
+ // dragstart/drag/dragend
+ el.addEventListener('dragstart', (event: DragEvent) => {
+ event.dataTransfer.setData('originId', el.id)
+ })
+ },
+}
diff --git a/packages/devui-vue/devui/dragdrop/src/droppable.directive.ts b/packages/devui-vue/devui/dragdrop/src/droppable.directive.ts
new file mode 100644
index 0000000000000000000000000000000000000000..d60618868e0b5dddab2599dc2f35d92b36aee14c
--- /dev/null
+++ b/packages/devui-vue/devui/dragdrop/src/droppable.directive.ts
@@ -0,0 +1,15 @@
+export default {
+ mounted(el: HTMLElement): void {
+ // dragenter/dragover/dragend/drop
+ el.addEventListener('dragover', (event: DragEvent) => {
+ event.preventDefault()
+ })
+
+ el.addEventListener('drop', (event: DragEvent) => {
+ const originId = event.dataTransfer.getData('originId')
+ const originNodeCopy = document.getElementById(originId).cloneNode(true)
+ const targetNode: any = event.target
+ targetNode.append(originNodeCopy)
+ })
+ },
+}
diff --git a/packages/devui-vue/docs/components/dragdrop/index.md b/packages/devui-vue/docs/components/dragdrop/index.md
new file mode 100644
index 0000000000000000000000000000000000000000..f37a25bf6a4c2eb7eb87088f440b4b4bed5343d5
--- /dev/null
+++ b/packages/devui-vue/docs/components/dragdrop/index.md
@@ -0,0 +1,117 @@
+# Dragdrop 拖拽
+
+拖拽组件。
+
+### 何时使用
+
+当需要使用数个操作步骤,且步骤的顺序需要灵活调整时。
+
+### 基本用法
+
+:::demo 从一个container拖动到另外一个container。
+
+```vue
+
+
+
+
+
+
+
+```
+
+:::
+
+### d-draggable 指令
+
+d-draggable 参数
+
+| 参数 | 类型 | 默认 | 说明 | 跳转 Demo | 全局配置项 |
+| ---- | ---- | ---- | ---- | --------- | --------- |
+| dragData | any | -- | 可选,转递给 DropEvent事件的数据 | [基本用法](#基本用法) | |
+| dragScope | string \| Array\ | 'default' | 可选,限制 drop 的位置,必须匹配对应的 dropScope | [基本用法](#基本用法) | |
+
+d-draggable 事件
+
+| 事件 | 类型 | 说明 | 跳转 Demo |
+| ---- | ---- | ---- | --------- |
+| dragStartEvent | EventEmitter\ | 开始拖动的 DragStart 事件 | [基本用法](#基本用法) |
+| dragEndEvent | EventEmitter\ | 拖动结束的 DragEnd 事件 | [基本用法](#基本用法) |
+| dropEndEvent | EventEmitter\ | 放置结束的 Drop 事件 | [基本用法](#基本用法) |
+
+### d-droppable 指令
+
+d-droppable 参数
+
+| 参数 | 类型 | 默认 | 说明 | 跳转 Demo | 全局配置项 |
+| ---- | ---- | ---- | ---- | --------- | --------- |
+| dropScope | string | Array\ | 'default' | 可选,限制 drop 的区域,对应 dragScope | [基本用法](#基本用法) | |
+
+d-droppable 事件
+
+| 事件 | 类型 | 说明 | 跳转 Demo |
+| ---- | ---- | ---- | --------- |
+| dragEnterEvent | EventEmitter\ | drag 元素进入的 dragenter 事件 | [基本用法](#基本用法) |
+| dragOverEvent | EventEmitter\ | drag 元素在 drop 区域上的 dragover 事件 | [基本用法](#基本用法) |
+| dragLeaveEvent | EventEmitter\ | drag 元素离开的 dragleave 事件 | [基本用法](#基本用法) |
+| dropEvent | EventEmitter\ | 放置一个元素, 接收的事件,其中 nativeEvent 表示原生的 drop 事件,其他见定义注释 | [基本用法](#基本用法) |
+
+