如何使用库存系统在 Vue/JS/HTML 中启用拖放功能?

问题描述 投票:0回答:1

我想重新创建一个像《我的世界》中的库存系统,因为它有助于理解很多 Web 开发内容,并且总体上成为一名更好的开发人员,我的代码无法正常工作并更新网格中的元素。

GridBlock.vue

<script setup lang="ts">
import { ref, type Ref } from 'vue'

//const props = defineProps(['item'])

const selected: Ref<HTMLElement | null> = ref(null)

const randomColor = () => {
  //#1f3f5f
  return `#${Math.floor(Math.random() * 10)}f${Math.floor(Math.random() * 10)}f${Math.floor(Math.random() * 10)}f`
}

const handleClick = (e: Event) => {
  let target = e.target as HTMLElement
  target.style.backgroundColor = randomColor()
}

const handleDragStart = (e: DragEvent) => {
  let target = e.target as HTMLElement
  selected.value = target
}

const handleDragOver = (e: DragEvent) => {
  e.preventDefault()
}

const handleDrop = (e: DragEvent) => {
  e.preventDefault()

  let target = e.currentTarget as HTMLElement

  if (selected.value && selected.value !== target) {
    const temp = target.innerHTML
    target.innerHTML = selected.value.innerHTML
    selected.value.innerHTML = temp
    selected.value = null
  }
}
</script>

<template>
  <div
    class="grid-block"
    draggable="true"
    @click="handleClick"
    @dragstart="handleDragStart"
    @dragover="handleDragOver"
    @drop="handleDrop"
  >
    <div class="item-block">
      {{ Math.floor(Math.random() * 100) }}
    </div>
  </div>
</template>

<style>
.grid-block {
  width: 4rem;
  height: 4rem;
  margin-left: auto;
  margin-right: auto;
  margin-top: 2rem;
  border: 2px solid red;
  background-color: beige;
}
.item-block {
  width: 100%;
  height: 100%;
  background-color: black;
}
</style>

GridDisplay.vue

<script setup lang="ts">
import GridBlock from './GridBlock.vue'

function range(start: number, end: number): number[] {
  return Array.from({ length: end - start + 1 }, (_, i) => start + i)
}

const blocks = range(1, 16)
</script>

<template>
  <div class="grid-container">
    <GridBlock v-for="i in blocks" :key="i" :id="i"></GridBlock>
  </div>
</template>

<style>
.grid-container {
  display: grid;
  grid-template-columns: repeat(4, 7.4rem);
  grid-template-rows: repeat(4, 7.4rem);
  border: 1px solid red;
  width: 25%;
  margin-left: auto;
  margin-right: auto;
  background-color: cadetblue;
}
</style>

我尝试询问 ChatGPT 我的逻辑是否有任何缺陷,我按照 Youtube 上关于 vanilla JS 中拖放功能的教程进行操作,然后尝试在 VUE 中实现它,我期望当我将一个网格块拖到另一个网格块之上时网格块时,目标网格块将获取所选网格块内的所有数据和样式,但什么也没有发生,并且我在调试工具中没有看到可用于修复此问题的详细信息或错误。我对这一切仍然是新手,所以我们将不胜感激。

javascript html vue.js dom dom-events
1个回答
0
投票

您从未将

selected
设置为值,并且您的大部分逻辑都包含在
if (selected.value && selected.value !== target)
中。

您可能需要使用此处的

dragenter
dragleave
事件
来确定您的物品被丢弃的位置。

您还将收到一个

DataTransfer
对象作为这些事件的一部分,其中包含您可能想要的信息。

另外,请查看 VueUse 中的

useDraggable
useDropZone
。他们做类似的事情,并且源代码可用

© www.soinside.com 2019 - 2024. All rights reserved.