Custom drag preview
In the previous chapter, you probably already noticed that the pointer event provider has a few caveats.
For example,
- you can't drag the item out of the scroll container
- the original place doesn't have a placeholder item there
The vue dnd has a mechanism for you to customize this behavior.
Setup
Before adding the preview, we need a container to contain the preview we want to render.
Due to css overflow
containers, this container is preferred to be put in the <body>
root.
This can be done with the vue <Teleport>
<!-- app.vue-->
<template>
<Box
v-for="box in boxes"
:index="box.id"
:key="box.id"
@drop="onDrop"
>
<Ball
v-for="item in box.items"
:key="item"
:from="box.id"
:index="item"
></Ball>
</Box>
<Teleport to="body">
<DragLayer />
</Teleport>
</template>
<script setup lang="ts">
import { DrayLayer } from '@mmis1000/vue-dnd'
/* ... */
</script>
<style>
/* ... */
</style>
Add preview to drag target
And now we add drag preview to drag target
import { computed, h } from "vue";
import { useDraggable } from '@mmis1000/vue-dnd';
import { BallType } from "./type";
import { BallPreview } from "./ball-preview";
const props = defineProps({
from: {
type: String,
required: true,
},
index: {
type: String,
required: true,
}
});
const { propsItem, state } = useDraggable(
BallType,
computed<[string, string]>(() => [props.index, props.from]),
{
preview: () => {
return h(BallPreview, { index: props.index })
}
}
);
import { computed } from "vue";
import { useDraggable } from '@mmis1000/vue-dnd';
import { BallType } from "./type";
import { BallPreview } from "./ball-preview";
const props = defineProps({
from: {
type: String,
required: true,
},
index: {
type: String,
required: true,
}
});
const { propsItem, state } = useDraggable(
BallType,
computed<[string, string]>(() => [props.index, props.from]),
{
preview: () => {
return <BallPreview index={props.index} />
}
}
);
The preview can be in whatever component you wish, but it must not cause side effects because it may be re-rendered at any time.
Result
example Source