Drop zone limit
In the previous guide, you probably already notice something went wrong. There is a problem that you can drop the ball into the box where it is already in.
In fact, vue dnd can limit what item a drop zone should accept.
Add the source to the message that dragging the item send to drop zone
Before adding a limit to the drop zone. we need to let drop zone know where the item was from.
But this information is not included in the previous guide.
So we need to add it.
/* type.ts */
import { createType } from '@mmis1000/vue-dnd'
// the DataType is what you used to identify the item for drag
// type DataType = string
type DataType = [item: string, from: string]
export const BallType = createType<DataType>()
<!-- ball.vue -->
<template>
<!-- ... -->
</template>
<script setup lang="ts">
import { computed } from "vue";
import { useDraggable } from '@mmis1000/vue-dnd';
import { BallType } from "./type";
const props = defineProps({
from: {
type: String,
required: true,
},
index: {
type: String,
required: true,
}
});
const { propsItem } = useDraggable(
BallType,
// computed(() => props.index)
computed<[string, string]>(() => [props.index, props.from])
);
</script>
<style>
/* ... */
</style>
<!-- app.vue -->
<template>
<Box
v-for="box in boxes"
:key="box.id"
>
<Ball
v-for="item in box.items"
:key="item"
:from="box.id"
:index="item"
></Ball>
</Box>
</template>
Add the message filter and handle message format change
And now there is the important part.
We need to make the system know whether we want to accept the message or not
<template>
<div
class="box"
v-bind="propsItem"
></div>
</template>
<script setup lang='ts'>
import { useDroppable } from '@mmis1000/vue-dnd';
import { BallType } from "./type";
const props = defineProps({
index: {
type: String,
required: true,
}
});
const emit = defineEmits<{
(ev: 'drop', item: [item: string, target: string]): void
}>()
const { propsItem } = useDroppable(
BallType.withFilter(([item, source]) => source !== props.index),
{
onDrop: (ev, [data, source]) => {
console.log(`${data} from ${source} is dropped into ${props.index}`)
emit('drop', [data, props.index])
}
}
);
</script>
<style>
/* ... */
</style>
Result
As the result, you are now not allowed to drop a ball into its own box.
example Source
a
b
AB
C