문서/API

useDnD와 모니터

프로바이더 아래 어디서든 쓰는 드래그 상태와 이벤트. 그리고 다른 Vue 앱에 넘겨주는 프로바이더 자체.

이 페이지 편집

이 페이지는 AI가 번역했으며 부정확한 내용이 있을 수 있습니다. 영어 원문 읽기

Live

데모 불러오는 중…

<script setup lang="ts">
import { DnDProvider } from '@vue-dnd-kit/core';
import TokenScene from './TokenScene.vue';
import StateInspector from './StateInspector.vue';
</script>

<template>
  <DnDProvider>
    <div class="demo">
      <TokenScene />
      <StateInspector />
    </div>
  </DnDProvider>
</template>

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

useDnD

function useDnD(): DnDState;

직접 만든 UI를 위한 읽기 전용 드래그 상태(유효한 대상 강조, 스피너, 진행률).

const { status, active, over, selection, cancel } = useDnD();
const dragging = computed(() => status.value === 'dragging');

프로바이더 드래그의 반응형 상태입니다. active와 over는 드롭이 결정되는 즉시 비워지며, 그동안 오버레이는 아직 안착하는 중입니다.

드래그 상태는 드롭이 결정되면 끝납니다. 오버레이가 아직 제자리로 애니메이션되는 동안에도 active, over, pointer는 null이 됩니다(droppable도 더 이상 받아들이지 않습니다). 파생된 UI는 이전 드래그와 새 데이터를 섞지 않습니다. 비동기 onBeforeDrop이 결정하는 동안 상태는 놓은 순간 그대로 유지되지만, 페이지는 드래그 모드에서 벗어납니다. 페이지 자체의 커서와 텍스트 선택이 돌아오고(확인 다이얼로그가 정상적으로 동작합니다), 오버레이는 드롭한 자리에서 기다립니다.

status는 드래그가 진행되는 동안 'dragging', 그렇지 않고 드롭이 결정되는 중이거나 오버레이가 아직 안착하는 중이면 'dropping', 그 밖에는 'idle'입니다('activating'과 'selecting'은 별도). 새 드래그는 안착을 기다리지 않습니다. 바로 시작되고, 안착은 그 주위에서 마무리됩니다.

Readonly<Ref<DnDStatus>>

프로바이더가 하고 있는 일(DnDStatus 참고).

Readonly<Ref<Active | null>>

진행 중인 드래그. 드래그가 없을 때, 그리고 드롭이 결정되는 즉시 null입니다.

Readonly<Ref<Over | null>>

드래그 아래에 있는 드롭 대상. 아무것도 없으면 null.

Readonly<Ref<Coordinates | null>>

뷰포트 좌표의 포인터(모디파이어 적용 후). 드래그가 없으면 null.

Readonly<Ref<Coordinates | null>>

over 안에서 드래그 중인 박스의 왼쪽 위 모서리가 있는 위치(실시간). 매 이동의 DnDEvent.position입니다. 아무것도 없는 곳 위에서는 null입니다. 오버레이 컴포넌트는 이 값을 읽어 안착할 위치(캘린더의 시간)를 보여 줍니다.

{ progress: Readonly<Ref<number>> }

progress: status가 'activating'인 동안, 누르기가 활성화 조건에 얼마나 다가갔는지를 0에서 1로 나타냅니다. 예: 길게 누르는 동안 채워지는 링.

Readonly<Ref<boolean>>

자동 스크롤이 컨테이너를 움직이고 있습니다.

DnDSelection

선택된 draggable(DnDSelection 참고).

() => void

드래그(원래 자리로 돌아갑니다) 또는 대기 중인 활성화를 취소합니다.

선택

선택된 draggable(id 기준): 그중 하나를 드래그하면 모두 함께 옮겨집니다(멀티 드래그). id로 보관하므로 선택은 언마운트된 뒤에도 남습니다(가상 리스트).

ReadonlySet<Key>

선택된 id. 반응형입니다.

(id: Key) => boolean

id가 선택되어 있는지.

(...ids: Key[]) => void

이 id들을 선택합니다.

(...ids: Key[]) => void

이 id들의 선택을 해제합니다.

(id: Key, force?: boolean) => void

id를 선택하거나 선택 해제합니다. force: true면 선택하고, false면 해제합니다.

(ids: Iterable<Key>) => void

이 id들만 선택하고 나머지는 선택하지 않습니다.

() => void

모든 id의 선택을 해제합니다.

useDnDMonitor

function useDnDMonitor(monitor: DnDMonitor): void;

프로바이더 아래의 모든 드래그 이벤트를 구독합니다. 호출한 컴포넌트(또는 effect scope)가 살아 있는 동안 유지됩니다.

useDnDMonitor({
  onDragEnd: (e) => (e.dropped ? save(e) : undefined),
  onBeforeDrop: async (e) => ((await confirm()) ? 'accept' : 'reject'),
});

드롭에 대해서는(onBeforeDrop) 대상보다 모니터에 먼저 묻습니다. 페이로드는 이벤트 페이지에 있습니다.

프로바이더 아래의 모든 드래그에 대한 훅(useDnDMonitor).

(event: DnDEvent) => void

활성화를 거쳐 드래그가 시작되었습니다.

(event: DnDEvent) => void

드래그가 움직였습니다(많아야 프레임당 한 번).

(event: DnDEvent) => void

드래그 아래의 대상이 바뀌었습니다.

(event: DnDEvent) => MaybePromise<BeforeDropResult>

드롭이 확정되기 전에 실행됩니다(BeforeDropResult 참고). 'reject'는 드롭을 거부하고, id 목록은 일부만 수락합니다.

(event: DnDEndEvent) => void

드롭이 끝난 뒤의 알림. 정렬 가능한 리스트는 이미 onDrop을 실행하고 기록했습니다.

(event: DnDEvent) => void

드래그가 취소되었거나 드롭이 거부되었습니다. 항목이 원래 자리로 돌아갑니다.

(event: DnDEvent) => void

onBeforeDrop이 'continue'로 응답했습니다. 드롭은 없었고 드래그가 계속됩니다.

(event: DnDEvent | DnDEndEvent) => void

끝난 드래그의 오버레이가 안착했습니다. 드롭 애니메이션(취소라면 원래 자리로 돌아가는 비행) 뒤에, onDragEnd(DnDEndEvent)나 onDragCancel이 받은 이벤트와 함께 호출됩니다. 그사이 다음 드래그가 이미 시작되었을 수 있습니다. 드래그는 안착을 기다리지 않습니다.

(event: KeyboardEvent, context: KeyboardMoveContext) => MaybePromise<Coordinates | undefined>

키보드 드래그: 화살표 키에 대한 다음 포인터 위치(예: 다음 정렬 자리).

화살표 키를 눌렀을 때 getKeyboardCoordinates가 받는 것.

Active

현재 드래그.

Coordinates

지금 드래그가 있는 위치(뷰포트 좌표).

Coordinates

누른 화살표 키의 단위 벡터.

useDnDContext와 provideDnDContext

function useDnDContext(): DnDContext;

이 컴포넌트 위에 있는 프로바이더로, provideDnDContext용 불투명 핸들입니다. 프로바이더를 shadow root와 별도의 Vue 앱으로 이어 줍니다.

function provideDnDContext(app: App, context: DnDContext): void;

프로바이더(useDnDContext()에서 얻은 것)를 다른 Vue 앱과 공유합니다. 예를 들어 shadow root 안에 마운트된 앱입니다.

// In a component under the provider:
const context = useDnDContext();
// A second Vue app (a widget mounted in a shadow root) joins the same drag:
const widget = createApp(Widget);
provideDnDContext(widget, context);

useDnDContext()가 반환하는 프로바이더. provideDnDContext()에 넘기면 다른 Vue 앱(예: shadow root에 마운트한 앱)도 같은 프로바이더로 동작합니다. 불투명 타입입니다. 공개 멤버가 없으므로 라이브러리 내부가 바뀌어도 변하지 않습니다.