UNPKG

@vdnd/v3

Version:

Easy used vue drag and drop component library.

274 lines (168 loc) 10.4 kB
# 简介 简单易用的拖拽放置 vue 组件库。 vdnd 只抽象出拖拽了什么以及将其放置在了哪里,而不实现具体的放置效果。 # 示例 ```typescript import { ref } from 'vue'; import { push, remove } from '@vdnd/v3'; import { useMouseDnd, MouseDnd, DndSource, DndDropzone } from '@vdnd/v3'; import type { DropEvent } from '@vdnd/v3'; const dnd = useMouseDnd<number>({ strict: true, }); const left = ref([1, 2, 3]); const right = ref<number[]>([]); const onDrop = (e: DropEvent<number>) => { if (e.source.label === 'left' && e.dropzone.label === 'right') { push(right, remove(left, e.source.value!)); } }; ``` ```html <MouseDnd :instance="dnd" class="example" @drop="onDrop"> <div> <DndSource v-for="(number, index) in left" :key="index" label="left" :value="index"> {{ number }} </DndSource> </div> <DndDropzone label="right"> <div v-if="!right.length" class="empty">拖到这里来</div> <div v-for="(number, index) in right" :key="index" class="right-box">{{ number }}</div> </DndDropzone> </MouseDnd> ``` [在线示例](http://zbd329.top/vdnd/?lang=zh-cn&index=0) # API ## 插件 ### NativeDndPlugin 注册全局组件:`NativeDnd``DndSource``DndDropzone``DndHandle`### MouseDndPlugin 注册全局组件:`MouseDnd``DndSource``DndDropzone``DndHandle`### TouchDndPlugin 注册全局组件:`TouchDnd``DndSource``DndDropzone``DndHandle`## 组件 ### DndProvider `DndProvider` 用于渲染**拖放容器**:只有来自该容器内的拖放(拖拽放置)交互才会被 `DndProvider` 感知。 vdnd 提供了 `NativeDnd``MouseDnd``TouchDnd` 三类 `DndProvider`,它们使用不同的事件描述拖放交互,例如: - `NativeDnd``dragstart` 事件的触发视为交互的开始; - `MouseDnd``mousedown``mousemove` 事件的接连触发视为交互的开始; - `TouchDnd``touchstart``touchmove` 事件的接连触发视为交互的开始。 #### 属性 | 名称 | 类型 | 说明 | 是否必选 | 默认值 | | -------- | ------ | ------------------------------------------- | -------- | ------ | | tag | string | 渲染**拖放容器**所使用的 html 标签 | 否 | 'div' | | instance | object | [拖放交互实例.md](./docs/zh-cn/instance.md) | 是 | | #### 插槽 | 名称 | 说明 | 参数 | 后备内容 | | ------- | -------------------- | ---- | -------- | | default | **拖放容器**的子节点 | 无 | 空 | #### 事件 | 名称 | 说明 | | ------------ | ------------------------------ | | drag | `API#DndSource` | | drag:start | `API#DndSource` | | drag:prevent | `API#DndSource` | | drag:enter | `API#DndDropzone` | | drag:over | `API#DndDropzone` | | drag:leave | `API#DndDropzone` | | drop | `API#DndDropzone` | | drag:end | `API#DndDropzone` | | initialized | `DndProvider` 初始化完成后触发 | 更多信息请参考[拖放交互事件.md](./docs/zh-cn/event.md)。 #### 组件实例 `DndProvider` 不使用 `expose` 暴露任何内容。 ### DndSource `DndSource` 用于渲染**源**:只有尝试拖拽**拖放容器**中的**源**时,`DndProvider` 才能感知到拖拽的发生。 #### 属性 | 名称 | 类型 | 说明 | 是否必选 | 默认值 | | --------- | ------- | ------------------------------------------------ | -------- | ------------------------------------- | | tag | string | 渲染**源**所使用的 html 标签 | 否 | 'div' | | label | string | 为**源**绑定一个标签,一般用于分组 | 否 | | | value | any | 为**源**绑定一个值,在某个组内,该值通常是唯一的 | 否 | | | draggable | boolean | 是否允许拖拽 | 否 | true | | dropzone | boolean | 是否同时作为**放置区域** | 否 | false | | droppable | boolean | 是否允许放置 | 否 | false;true,当 `dropzone` 为 true 时 | 当我们尝试拖拽一个可拖拽的**源**时,拖放交互开始,`DndProvider` 触发 `drag:start` 事件,并将该**源**作为**当前拖拽源**。反之,拖放交互被阻止,`DndProvider` 触发 `drag:prevent` 事件。拖放交互开始后,`DndProvider` 将会定时触发 `drag` 事件。 `DndProvider` 触发事件时,会将相关的**源**作为参数,并支持访问**源**的属性,例如 `label``value`:它们可以帮助我们快速识别出**源**的身份,并以此决定后续的操作。 > `label` 属性只是起到标记作用,vdnd 内部并没有任何关于分组的逻辑。 **源**可以同时作为**放置区域**,这会带来更多可能性。在后面,我们将了解到**放置区域**#### 插槽 | 名称 | 说明 | 参数 | 后备内容 | | ------- | -------------- | ---- | -------- | | default | **源**的子节点 | 无 | 空 | #### 事件 `DndSource` 不触发任何事件。 #### 组件实例 `DndSource` 不使用 `expose` 暴露任何内容。 ### DndDropzone `DndDropzone` 用于渲染**放置区域**:一般来说,只有当我们在**放置区域**上结束拖放交互时,才可能产生实际的放置效果,例如将**当前拖拽源**移动到交互结束时所在的**放置区域**中。 #### 属性 | 名称 | 类型 | 说明 | 是否必选 | 默认值 | | --------- | ------- | ------------------------------------------------------ | -------- | ------ | | tag | string | 渲染**放置区域**所使用的 html 标签 | 否 | 'div' | | label | string | 为**放置区域**绑定一个标签,一般用于分组 | 否 | | | value | any | 为**放置区域**绑定一个值,在某个组内,该值通常是唯一的 | 否 | | | droppable | boolean | 是否允许放置 | 否 | true | 在拖放交互开始后,当我们使用某种指向设备(例如鼠标)指向某个**放置区域**时,`DndProvider` 将会触发 `drag:enter` 事件,并将该**放置区域**作为**当前选择放置区域**。当我们取消指向**当前选择放置区域**时,`DndProvider` 将会触发 `drag:leave` 事件。 在拖放交互进行中时,如果**当前选择放置区域**存在,`DndProvider` 将会定时触发 `drag:over` 事件。 在拖放交互结束时,如果**当前选择放置区域**不存在,`DndProvider` 将只会触发 `drag:end` 事件。否则,`DndProvider` 将会根据**当前选择放置区域**的可放置与否决定触发 `drop``drag:leave` 事件,并随后触发 `drag:end` 事件。 #### 插槽 | 名称 | 说明 | 参数 | 后备内容 | | ------- | -------------------- | ---- | -------- | | default | **放置区域**的子节点 | 无 | 空 | #### 事件 `DndDropzone` 不触发任何事件。 #### 组件实例 `DndDropzone` 不使用 `expose` 暴露任何内容。 ### DndHandle `DndHandle` 用于渲染**拖拽触发器**。如果某个**源**中包含**拖拽触发器**,那么只有当我们尝试拖拽该**源**中的**拖拽触发器**时,`DndProvider` 才能感知到我们正在尝试拖拽该**源**,并随后触发 `drag:start``drag:prevent` 事件。 #### 属性 | 名称 | 类型 | 说明 | 是否必选 | 默认值 | | ---- | ------ | ------------------------------------ | -------- | ------ | | tag | string | 渲染**拖拽触发器**所使用的 html 标签 | 否 | 'div' | #### 插槽 | 名称 | 说明 | 参数 | 后备内容 | | ------- | ---------------------- | ---- | -------- | | default | **拖拽触发器**的子节点 | 无 | 空 | #### 事件 `DndHandle` 不触发任何事件。 #### 组件实例 `DndHandle` 不使用 `expose` 暴露任何内容。 ## 组合式函数 ### useDnd 创建一个[拖放交互实例](./docs/zh-cn/instance.md),通过选项 `type` 区分实例种类。 ### useNativeDnd 创建一个 `NativeDnd` 专用的[拖放交互实例](./docs/zh-cn/instance.md)。 ### useMouseDnd 创建一个 `MouseDnd` 专用的[拖放交互实例](./docs/zh-cn/instance.md)。 ### useTouchDnd 创建一个 `TouchDnd` 专用的[拖放交互实例](./docs/zh-cn/instance.md)。 ## 数组工具函数 vdnd 提供了一组更新响应式数组的工具函数,在实现具体的放置效果时会十分有帮助。 ### unshift 在数组头部插入一个元素。 ### shift 移除数组中的第一个元素。 ### push 在数组尾部插入一个元素。 ### pop 移除数组中的最后一个元素。 ### splice 移除数组中的多个元素,并可以在移除的位置上插入多个元素。 ### find 返回第一个满足条件的元素(从左向右查找)。 ### findLast 返回第一个满足条件的元素(从右向左查找)。 ### findIndex 返回第一个满足条件的元素的索引(从左向右查找)。 ### findLastIndex 返回第一个满足条件的元素的索引(从右向左查找)。 ### swap - 交换两个数组中的元素。 - 交换一个数组中的两个元素。 ### remove 移除数组中满足条件的第一个元素。 ### insert 在数组某个位置的前或后插入多个元素。 # 感谢 [@shopify/draggable](https://www.npmjs.com/package/@shopify/draggable)为 vdnd 带来了灵感。