文档/API

makeDroppable

让元素成为放置目标,带有决定接收什么的规则和用于放置的钩子。

编辑此页

本页由 AI 翻译,可能存在不准确之处。 阅读英文原文

function makeDroppable<TData = unknown>(  target: MaybeElementRef,  options?: DroppableOptions<TData>,): DroppableReturn;

让元素成为放置目标。

const zone = useTemplateRef<HTMLElement>('zone');
const { isOver, isAccepting } = makeDroppable(zone, {
  accept: 'image',
  onDrop: (e) => move(e.active.id),
});

参见拖放和决定放置。

Live

正在加载演示…

<script setup lang="ts">
import { reactive } from 'vue';
import { DnDProvider, type Key } from '@vue-dnd-kit/core';
import FileChip from './FileChip.vue';
import Zone from './Zone.vue';
import { FILES } from './files';

/** Which zone each file is in. */
const where = reactive<Record<string, string>>(Object.fromEntries(FILES.map((file) => [file.id, 'desk'])));
const filesIn = (zone: string) => FILES.filter((file) => where[file.id] === zone);
const move = (zone: string, file: Key) => (where[String(file)] = zone);
</script>

<template>
  <DnDProvider>
    <div class="zones">
      <Zone title="Desktop" rule="takes anything" class="desk" @drop="move('desk', $event)">
        <FileChip v-for="file in filesIn('desk')" :key="file.id" :file="file" />
      </Zone>
      <Zone title="Images" rule="accept: 'image'" accept="image" @drop="move('images', $event)">
        <FileChip v-for="file in filesIn('images')" :key="file.id" :file="file" />
      </Zone>
      <Zone title="Media" rule="accept: ['image', 'audio']" :accept="['image', 'audio']" @drop="move('media', $event)">
        <FileChip v-for="file in filesIn('media')" :key="file.id" :file="file" />
      </Zone>
      <Zone title="Archive" rule="disabled: true" disabled @drop="move('archive', $event)" />
    </div>
  </DnDProvider>
</template>

<style scoped>
.zones {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
  width: min(720px, 100%);
}

.desk {
  grid-column: 1 / -1;
}

@media (max-width: 560px) {
  .zones {
    grid-template-columns: minmax(0, 1fr);
  }
}
</style>

选项

makeDroppable 的选项。

放进项中。可排序项的元素上(或其内部)的放置目标和其他地方的一样工作,只有一条规则,适用于该项所在的列表本会对拖拽进行排序的时候:只有指针位于项的中间(沿列表轴向的 25–75%;网格中为 x 方向)时它才生效,在那里放置会进入目标,列表不会为它移动。靠近项的边缘时,列表照常排序。accept 拒绝该拖拽的目标会被排除,所以列表在该项上方照常排序,就像在其他项上方一样(无需禁用它)。键盘会先停在这样的目标上,然后才越过它所在的项。拖拽永远不会以它携带的东西为目标:被拖拽项之中(或之上)的目标不算,被拖拽项落入的位置中的目标也不算。要在 onDrop 中把这些项从它们的列表中移出,调用 e.source.remove()。

除回调外,每个选项都接受值、ref 或 getter(accept、overOverlay、overDropAnimation:值或 ref),并在拖拽寻找目标时实时读取。

Key值 · ref · getter

默认:useId(),在服务端和客户端渲染之间保持稳定。

TData值 · ref · getter

关于这个目标的任何信息:事件以 over.data 携带它。

string值 · ref · getter

人们对它的称呼:屏幕阅读器文本会说出它,而不是 id(over Trash);事件以 over.label 携带它。

AcceptRule值 · ref

这个目标接收什么。在可排序项内部时,拒绝这次拖拽的目标会让列表在它上方排序。值或 ref:函数即规则。

AcceptMode值 · ref · getter

默认为 'all'。

boolean值 · ref · getter

true:拖拽经过它时就像它不存在一样。

number值 · ref · getter

目标重叠但不嵌套时,值较高的优先(默认 0)。可排序项胜过容器。

Component值 · ref

当这个目标接受的拖拽位于它上方时,浮层显示什么:一个获得 OverlayProps 的组件,代替拖拽自己的浮层(被拖拽项的组件、provider 的插槽或克隆)渲染,并把后者作为默认插槽获得,可以包裹它,也可以省略它(<slot />)。放置落到这里时它保持显示。没有浮层的拖拽(overlay: false)仍然没有浮层。值或 ref,实时读取;组件的切换使用 provider 的 overlayTransition 动画。(在可拖拽元素、项和列表上,overlay 是拖拽自己的浮层;可排序列表和树也以 overOverlay 接受这个选项。)

DropAnimation值 · ref

浮层被放到这里时如何落位,替代被拖拽项和 provider 的 dropAnimation:false 让它停在放下的地方(浮层组件自己的动画,比如溅开,会在那里播放),函数则为它添加动画。值或 ref,在放置时读取。

(event: DnDEvent) => void

拖拽来到了这个目标上方,无论它是否接受这次拖拽(event.over.accepted)。

(event: DnDEvent) => void

拖拽离开了这个目标。

(event: DnDEvent) => MaybePromise<BeforeDropResult>

在这个目标上的放置生效之前询问,位于监听器的 onBeforeDrop 之后,前提是它接受这次拖拽(见 BeforeDropResult)。可以是异步的:浮层在松开的地方等待。抛出错误会拒绝这次放置。

(event: DnDEndEvent) => void

这个目标上的放置已生效:执行它所代表的操作(移动项、上传文件)。当 onBeforeDrop 只接受了部分被拖拽的项时,event.accepted 是它们的 id,event.rejected 是其余的 id,这些项会飞回原处;active 仍然是整个拖拽。

ExternalAccept值 · ref · getter

接收来自页面之外的拖拽:来自桌面的文件、来自另一个应用或标签页的链接或文本(浏览器的拖放)。它们和本库的拖拽一样工作(isOver、isAccepting、各个事件),放置时 e.external 中有它们的数据。没有 external 的目标会忽略它们。值、ref 或 getter,实时读取。

返回值

makeDroppable 的返回值。

ComputedRef<Key>

目标的 id:id 选项,或为它生成的 id。

ComputedRef<boolean>

有拖拽位于它上方(使用 external 时,也包括来自页面之外的拖拽)。

ComputedRef<boolean>

有东西正在被拖拽,并且这个目标接收它。

ComputedRef<Placement | null>

悬停时,指针相对于目标各半部分的位置。

接收规则

'*' 或省略表示接收所有。没有类型的项符合任何字符串规则(与 v2 的 groups: [] 行为一致)。

type AcceptRule = | '*' | string | string[] | ((context: AcceptContext) => boolean)

函数形式的 accept 规则被调用时收到的参数。

Active

这次拖拽。

DragItem[]

所有被拖拽的项。

string[]

所有被拖拽项的类型合在一起。

'all':每个被拖拽的项都必须匹配;'some':至少一个(其余的可以在 onBeforeDrop 中拒绝)。

type AcceptMode = 'all' | 'some'

来自页面之外

external 从来自页面之外的拖拽中接收什么,以及这类拖拽携带什么(e.external)。参见文件与其他应用。

放置目标、列表或树从来自页面之外的拖拽中接收什么:来自桌面的文件、来自另一个应用或标签页的链接或文本(external)。

boolean | string | readonly string[] | ((file: ExternalFile) => boolean)

文件:true 接收任何文件。或者按 <input accept> 的写法:MIME 类型(image/*、application/pdf)和扩展名(.md),可以是逗号分隔的字符串或列表;扩展名在放置时检查。或者是一个对每个文件逐一询问的函数(返回 false 表示拒绝该文件)。从不接收文件夹。

boolean

一次接收多个文件(默认 true);false 会拒绝多于一个文件的拖拽。

boolean

纯文本(text/plain):从另一个应用拖来的一段选中内容。

readonly string[]

它接收的其他 MIME 类型,写法与其他应用提供它们时完全一致。

来自页面之外的拖拽(Active.external、DnDEvent.external)。拖拽进行时,浏览器只告知它携带了什么,而不给出数据:文件、链接和文本在放置时到来(ready)。

readonly string[]

它提供的 MIME 类型(Files、text/uri-list、text/plain、某个应用自己的类型)。

readonly string[]

它的文件的 MIME 类型,每个文件一个(浏览器无法判断时为 '')。

readonly File[]

放置时:目标接收的文件(不含文件夹和被拒绝的文件)。

readonly string[]

放置时:它的链接(text/uri-list)。

string

放置时:它的纯文本。

string

放置时:它的 HTML。

(type: string) => string

放置时:它提供的任意类型的数据(放置之前,以及对于它不提供的类型,为 '')。

boolean

它已被放下:上面的数据已经可用。

string

从应用另一个窗口拖进来的本库的项(native):它们的可排序分组的名称。该分组的列表会接收它们,就像它们来自自己的某个列表一样;active.items 中包含它们。

来自外部的拖拽中的一个文件,即询问 ExternalAccept.files 时传入的形式。文件悬停在页面上方时,浏览器只告知它们的类型:name 和 size 在放置时到来。

string

它的 MIME 类型(image/png);浏览器无法判断时为 ''。

string

带扩展名的文件名(notes.md),在放置时可用。

number

以字节为单位的大小,在放置时可用。

位置

指针位于被悬停的放置目标的哪几个半区(DroppableReturn.placement)。

boolean

在上半部分。

boolean

在右半部分。

boolean

在下半部分。

boolean

在左半部分。