文档/API

修饰器与碰撞检测

改变被拖拽项去向的函数,以及选出它下方目标的函数。

编辑此页

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

Live

正在加载演示…

<script setup lang="ts">
import { ref } from 'vue';
import { DnDProvider, closestCenter, closestCorners, pointerFirst, pointerWithin, rectIntersection } from '@vue-dnd-kit/core';
import ModifierLab from './ModifierLab.vue';

// Collision detection is the provider's: it picks the target, here one of the two pads.
const COLLISIONS = { pointerFirst, pointerWithin, rectIntersection, closestCenter, closestCorners };
const collision = ref<keyof typeof COLLISIONS>('pointerFirst');
</script>

<template>
  <DnDProvider :collision="COLLISIONS[collision]">
    <div class="demo">
      <code class="call">&lt;DnDProvider :collision="{{ collision }}"&gt;</code>
      <div class="collisions" role="radiogroup" aria-label="collision">
        <label v-for="name in Object.keys(COLLISIONS)" :key="name" :class="{ on: collision === name }">
          <input v-model="collision" type="radio" :value="name" />
          {{ name }}
        </label>
      </div>
      <ModifierLab />
    </div>
  </DnDProvider>
</template>

<style scoped>
.demo {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
}

.collisions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 2px;
  max-width: 100%;
  padding: 3px;
  border-radius: 9px;
  background: color-mix(in srgb, currentColor 7%, transparent);
}

.call {
  font: 11px/1.4 ui-monospace, Menlo, Consolas, monospace;
  color: #42b883;
}

label {
  padding: 4px 8px;
  border-radius: 6px;
  font: 11px/1.3 ui-monospace, Menlo, Consolas, monospace;
  cursor: pointer;
}

label.on {
  background: Canvas;
  box-shadow: 0 1px 3px rgb(0 0 0 / 0.25);
  font-weight: 600;
}

label:has(input:focus-visible) {
  outline: 2px solid #42b883;
}

input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}
</style>

修饰器

import { restrictToParent, snapToGrid } from '@vue-dnd-kit/core';

makeSortableList(list, { items, modifiers: [restrictToParent] });
makeDragArea(board, { modifiers: [snapToGrid({ x: 24, y: 24, smooth: true })] });

修饰器接收拖拽的偏移量,并返回一个新的偏移量。它们按顺序运行:provider 的 modifiers、拖拽区域的、可拖拽元素自己的(或其列表的),然后是区域的边界(restrictToArea),最后是 axis 锁定。参见轴、边界与网格。

Modifier

只在垂直方向移动:水平方向上,无论页面如何滚动,它都跟随开始时所在的内容(containerShift)。axis: 'y' 选项做的是同样的事,并且最后应用。

Modifier

只在水平方向移动:垂直方向上,无论页面如何滚动,它都跟随开始时所在的内容(containerShift)。axis: 'x' 选项做的是同样的事,并且最后应用。

Modifier

把浮层限制在窗口内。

Modifier

把浮层限制在拖拽开始时所在的容器内:可排序列表(而不是它的 DOM 父元素),对于普通的可拖拽元素则是父元素。

(target: MaybeElementRef) => Modifier

把浮层限制在某个元素内:元素本身、ref 或 getter。

Modifier

把浮层限制在被拖拽元素的第一个可滚动祖先元素内。

(size: number | SnapToGridOptions) => Modifier

把浮层吸附到网格上最近的单元格:数字表示正方形单元格的尺寸;选项可以分别设置每个轴、网格的起点,以及在单元格之间的滑动(SnapToGridOptions)。

Modifier

让浮层中心对准指针,而不是保持抓取时的偏移。

snapToGrid 的选项。

x?
number

单元格宽度,单位 px。不设置(或为 0)时,拖拽沿 x 轴自由移动。

y?
number

单元格高度,单位 px。不设置(或为 0)时,拖拽沿 y 轴自由移动:{ y: 15 } 只吸附日历事件的时间。

'container' | 'delta'

'container'(默认):浮层的左上角落在从容器左上角开始绘制的网格线上(containerRect:可排序列表或父元素)。'delta':对拖拽偏移量取整,项开始时与网格的错位会保留下来。

boolean | AnimationOptions

让浮层在吸附位置之间滑动(默认 80ms)。碰撞检测仍然立即使用吸附后的位置。

改变被拖拽项去往的位置:接收拖拽的偏移量(transform)并返回新的偏移量。

type Modifier = (args: ModifierArgs) => Coordinates

修饰器在拖拽每次移动时收到的参数。

Coordinates

相对拖拽起点的偏移量,已经过前面的修饰器处理。

Active

这次拖拽。

Rect

拖拽开始时被拖拽元素的矩形。

Rect

假如浮层盒子按 transform 移动、并保持当前尺寸时的矩形。使用 overlayFit: 'slot' 时,盒子会围绕指针调整尺寸,所以它并不总是等于按 transform 移动后的 activeRect。

Coordinates

拖拽开始时的指针位置。

Rect | null

被拖拽项所在的可排序列表容器(或父元素)的当前位置(它会跟随滚动)。

Coordinates

拖拽开始时所在的内容自开始以来在屏幕上移动了多远:容器本身移动了(页面或它外层的容器滚动了、布局发生了偏移),以及它的内容在容器内滚动了。轴锁定把另一个轴保持在这个偏移上,所以拖拽会停留在该内容中它所在的那一行或那一列。

Rect

窗口(视口)的矩形。

Over | null

拖拽下方的放置目标,以最近一次找到的为准;不在任何目标上方时为 null。

碰撞检测

import { closestCorners } from '@vue-dnd-kit/core';
<DnDProvider :collision="closestCorners" />

provider 的 collision 负责选出目标;最佳候选排在最前。

CollisionDetection

默认:指针下方的目标,否则是浮层重叠的目标。

CollisionDetection

指针下方的目标,来自命中测试:遵循 z-order、浮层和 shadow root。

CollisionDetection

与浮层重叠的目标:先比优先级,再比嵌套深度,最后比交并比(intersection over union)。

CollisionDetection

所有目标,按中心之间的距离排序。

CollisionDetection

所有目标,按各角之间的距离之和排序(适合堆叠的目标,例如看板的列)。

返回候选 id,最佳的在前。

type CollisionDetection = (args: CollisionArgs) => Key[]

碰撞检测在拖拽每次移动时收到的参数。

Coordinates

视口坐标中的指针位置,已应用修饰器。

Rect | null

被拖拽的盒子(浮层,或在 overlay: false 时元素本身)被拖到的位置上的矩形。

CollisionCandidate[]

拖拽可能去往的每个放置目标,无论它的 accept 规则是否接受这次拖拽。

Key[]

通过命中测试得到的指针下方的放置目标(遵循 z 轴顺序和 shadow root),最佳的在前。

碰撞检测可以选中的放置目标:已启用、在页面上且没有被完全裁剪。

Key

放置目标的 id。

Rect

目标的可见部分:经过其滚动容器和视口裁剪。

number

目标的 priority(默认 0):目标重叠但没有嵌套时,值高的胜出。可排序项胜过容器。

number

在放置目标之间的嵌套层级:顶层为 0,越深的目标值越大。