モニター(useDnDMonitor)、プロバイダーのイベント、ドロップゾーンのフックは DnDEvent を受け取り、onDragEnd は DnDEndEvent を受け取ります。並べ替え可能なリストとツリーは、独自のドロップイベント(SortableDropEvent、SortableTreeDropEvent)を自身の onBeforeDrop と onDrop に渡します。
デモを読み込み中…
<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 | nullover の中で、ドラッグ中のボックスの左上の角がある位置。パディングの端から測り、スクロール量を含みます:絶対配置したアイテムをドロップされた場所に置くための left/top です(ボード上のメモなど)。何もない上では null。オーバーレイのボックスの位置で、overlay: false の場合は要素自体の位置です。
DragModeドロップで何が起きるか:'move'、'copy'(リストの pull: 'clone'、または clone できるリストのアイテムの上でコピーのモディファイアキーを押している場合)、'swap'、'insert'。通常のドロップターゲットは、移動の代わりにコピーするためにこれを読み取ります。
DragSourceドラッグ中のアイテムが並べ替え可能なリストから来た場合に存在します。
ExternalDataページの外からのドラッグ:それが運ぶもの(active.external)。データはドロップ時に届きます。
DnDEndEvent
onDragEnd(とターゲットの onDrop)が受け取るもの:ドロップのイベントと、その結果。
booleanドラッグがすべてのドロップターゲットの外で終わった場合は false。
Key[]onBeforeDrop が受け入れた id(一部が返されなかった限り、ドラッグ中のすべての 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 から切り離されることがあります(仮想リスト、リスト間の移動)。
Rectドラッグ開始時の element のレイアウト上の矩形。
SensorTypeドラッグの動き方:'pointer' は座標に追従し、'keyboard' はアイテム単位で動きます(SensorActivation.type)。
ExternalDataページの外からのドラッグ(ファイル、リンク、テキスト、またはアプリの別のウィンドウからのアイテム):それが運ぶもの。その items はこのドラッグのために作られます(element は代役です)。
booleanブラウザー自身のドラッグ(native、または外部からのドラッグ):ドラッグ中の画像はブラウザーが描き、オーバーレイはありません。
ドラッグされている 1 つのアイテム:ドラッグの起点となったもの、またはマルチドラッグのほかのアイテム。
ターゲット
ドラッグの下にあるドロップターゲット。
ソース
ドラッグされているアイテムの出どころ(それが並べ替え可能なリストの場合)。
ドロップが何をするか:'move'、'copy'(アイテムは残り、そのコピーが入ります)、'swap'(behavior: 'swap':2 つのアイテムが場所を入れ替えます)、または 'insert'(通常のドラッグ可能な要素が、リストの createItem が作ったアイテムとしてリストに入ります)。
type DragMode = 'move' | 'copy' | 'swap' | 'insert'