Документация/API

События

Что несут события драга — активный драг, цель, указатель, положение элемента — и что отвечает onBeforeDrop.

Редактировать страницу

Страница переведена ИИ и может содержать неточности. Читать английский оригинал

Мониторы (useDnDMonitor), события провайдера и хуки droppable получают DnDEvent; onDragEnd получает DnDEndEvent. Сортируемые списки и деревья передают в свои onBeforeDrop и onDrop собственные события броска (SortableDropEvent, SortableTreeDropEvent).

Live

Загружаем демо…

<script setup lang="ts">
import { ref } from 'vue';
import { DnDProvider } from '@vue-dnd-kit/core';
import { describe, type LoggedEvent } from './describe';
import TaskColumn from './TaskColumn.vue';
import EventInspector from './EventInspector.vue';

const todo = ref([
  { id: 'docs', title: 'Write docs' },
  { id: 'bug', title: 'Fix #42' },
]);
const done = ref([{ id: 'ship', title: 'Ship v3' }]);

// Every event of the drag, described when it fires. A new drag starts a new log;
// moves fire every frame, so they share one entry, which keeps the latest.
const events = ref<LoggedEvent[]>([]);
let count = 0;
const record = (name: string, type: string, payload: unknown) => {
  if (name === 'onDragStart') events.value = [];
  const lines = describe(type, payload);
  const move = name === 'onDragMove' && events.value.find((event) => event.name === name);
  if (move) Object.assign(move, { lines, count: move.count + 1 });
  else events.value.push({ id: ++count, name, type, lines, count: 1 });
};
</script>

<template>
  <DnDProvider>
    <div class="demo">
      <div class="columns">
        <TaskColumn id="todo" v-model="todo" :record="record" />
        <TaskColumn id="done" v-model="done" :record="record" />
      </div>
      <EventInspector :events="events" :record="record" />
    </div>
  </DnDProvider>
</template>

<style scoped>
.demo {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: center;
  gap: 16px;
}

.columns {
  display: flex;
  flex-direction: column;
  gap: 10px;
  width: 168px;
}
</style>

DnDEvent

Что несут события драга: их получают мониторы, события провайдера и хуки целей.

Active<T>

Драг.

Over | null

Цель под драгом; null, если драг ни над чем.

Coordinates

Указатель в координатах вьюпорта, после модификаторов.

Coordinates

Смещение от начала драга, после модификаторов.

Coordinates | null

Где в over находится левый верхний угол перетаскиваемого блока — от края padding и с учётом прокрутки: те left/top, которые ставят абсолютно спозиционированный элемент туда, где его бросили (заметка на доске). null, если под драгом ничего нет. Берётся блок оверлея или, при overlay: false, сам элемент.

DragMode

Что сделал бы бросок: 'move', 'copy' (pull: 'clone' списка или клавиша копирования, зажатая над элементами, чей список умеет clone), 'swap' или 'insert'. Обычная цель читает его, чтобы копировать вместо перемещения.

DragSource

Есть, если перетаскиваемые элементы взяты из сортируемого списка.

ExternalData

Драг извне страницы: что он несёт (active.external). Его данные приходят при броске.

DnDEndEvent

Что получает onDragEnd (и onDrop цели): событие броска и то, чем он закончился.

boolean

false, если драг закончился вне всех целей.

Key[]

Id, принятые в onBeforeDrop (все перетаскиваемые id, если не была возвращена их часть).

Key[]

Остальные перетаскиваемые id: onBeforeDrop их не включил, и они улетают обратно. Пусто, если он принял все.

'move' | 'copy' | 'link'

Драг за пределы страницы (native), брошенный где-то ещё: что это место с ним сделало. 'move' забирает элементы из их сортируемого списка здесь; 'copy' и 'link' оставляют их.

Ответы onBeforeDrop

Что решает onBeforeDrop:

  • 'accept' (или true, или ничего): бросок проходит;
  • 'reject' (или false): броска нет, элементы улетают обратно;
  • список id: приняты только эти элементы, остальные улетают обратно;
  • 'continue': броска нет, и драг продолжается. С указателем элемент снова следует за ним (без зажатой кнопки), и следующее отпускание, то есть клик, бросает его; касание снова берёт его; клавиатура двигает его как прежде. Escape отменяет драг. Бросок снова спрашивает onBeforeDrop.
type BeforeDropResult = boolean | void | Key[] | 'accept' | 'reject' | 'continue'

См. решение о броске.

Активный драг

Текущий драг: элемент, с которого он начался, и все элементы, которые он несёт.

Key

Id элемента, с которого начался драг.

Key[]

Все перетаскиваемые id, основной — первым (мульти-драг).

DragItem<T>[]

Все перетаскиваемые элементы, основной — первым.

unknown

data элемента, с которого начался драг.

string

label элемента, с которого начался драг, — название для людей.

string[]

Нормализованный type элемента, с которого начался драг; пустой подходит к любой цели.

HTMLElement

DOM-элемент, с которого начался драг. Он может оказаться отсоединённым от DOM (виртуальные списки, перенос между списками).

Rect

Прямоугольник element в раскладке в начале драга.

SensorType

Как движется драг: 'pointer' следует за точками, 'keyboard' переходит по элементам (SensorActivation.type).

ExternalData

Драг извне страницы (файлы, ссылка, текст или элементы из другого окна приложения): что он несёт. Его items созданы для него (element — заглушка).

boolean

Собственный драг браузера (native или пришедший извне): перетаскиваемое изображение рисует браузер, оверлея нет.

Один перетаскиваемый элемент: тот, с которого начался драг, или ещё один из мульти-драга.

Key

Id его перетаскиваемого элемента (у элемента сортируемого списка — ключ).

T

Объект элемента, если драг идёт из сортируемого списка.

unknown

Его опция data.

string

Его label — название для людей.

string[]

Нормализованный type перетаскиваемого элемента; пустой подходит к любой цели.

Цель

Цель под драгом.

Key

Id цели.

unknown

Опция data цели.

string

label цели — название для людей.

HTMLElement

DOM-элемент цели.

Rect

Прямоугольник element, измеренный во время драга.

boolean

Принимает ли правило accept цели перетаскиваемые элементы.

Источник

Откуда взяты перетаскиваемые элементы, если это сортируемый список.

Key

Сортируемый список, из которого взяты перетаскиваемые элементы.

() => void

Удаляет перетаскиваемые элементы из их списка (для зон-корзин).

Что делает бросок: 'move', 'copy' (элементы остаются на месте, вставляются их копии), 'swap' (behavior: 'swap': два элемента меняются местами) или 'insert' (обычный перетаскиваемый элемент попадает в список как элемент, созданный его createItem).

type DragMode = 'move' | 'copy' | 'swap' | 'insert'