白云苍狗

白云苍狗

马上订阅 白云苍狗 RSS 更新: https://www.imalun.com/atom.xml

手撸 Grid 拖拽布局

2023年11月30日 20:07

最近有个需求需要实现自定义首页布局,需要将屏幕按照 6 列 4 行进行等分成多个格子,然后将组件拖拽对应格子进行渲染展示。

示例

对比一些已有的插件,发现想要实现产品的交互效果,没有现成可用的。本身功能并不是太过复杂,于是决定自己基于 vue 手撸一个简易的 Grid 拖拽布局。

完整源码在此,在线体验

概况

需要实现 Grid 拖拽布局,主要了解这两个东西就行

  • 拖放 API,关于拖放 API 介绍文章有很多 ,可以直接看 MDN 里拖放 API介绍,可以说很详细了。
  • Grid 布局, Grid 布局与 Flex 布局很相似,但是 Grid 像是二维布局,Flex 则为一维布局,Grid 布局远比 Flex 布局强大。MDN 关于网格布局介绍

需要实现主要包含:

  • 组件物料栏拖拽到布局容器
  • 布局容器 Grid 布局
  • 放置时是否重叠判断
  • 拖拽时样式
  • 放置后样式
  • 容器内二次拖拽

拖放操作实现

拖拽中主要使用到的事件如下

  • 被拖拽元素事件:
事件 触发时刻
dragstart 当用户开始拖拽一个元素或选中的文本时触发。
drag 当拖拽元素或选中的文本时触发。
dragend 当拖拽操作结束时触发
  • 放置容器事件:
事件 触发时刻
dragenter 当拖拽元素或选中的文本到一个可释放目标时触发。
dragleave 当拖拽元素或选中的文本离开一个可释放目标时触发。
dragover 当元素或选中的文本被拖到一个可释放目标上时触发。
drop 当元素或选中的文本在可释放目标上被释放时触发。

可拖拽元素

让一个元素能够拖拽只需要给元素设置 draggable="true" 即可拖拽,拖拽事件 API 提供了 DataTransfer 对象,可以用于设置拖拽数据信息,但是仅仅只能 drop 事件中获取到。因为我们需要在拖拽中就需要获取到拖拽信息,用来显示拖拽时样式,所以需要自己处理这些信息存储起来,以便读取。

需要处理主要是,在拖拽时将 将当前元素信息设置到 dragStore 中,结束时清空当前信息。

html
<script setup lang="ts">
  import { dragStore } from "./drag";

  const props = defineProps<{
    data: DragItem;
    groupName?: string;
  }>();...

剩余内容已隐藏

查看完整文章以阅读更多