当前位置: 首页 > news >正文

讲讲项目里的仪表盘编辑器(三)布局组件

布局容器处理

        看完前面两章的讲解,我们对仪表盘系统有了一个大概的理解。接着我们讲讲更深入的应用。

        上文讲解的编辑器只是局限于平铺的组件集。而在编辑器中,还会有一种组件是布局容器。它允许其他组件拖拽进入在里面形成自己的一套布局。典型的有分页卡、布局容器等组件。

布局组件的放置

        与前两章提到的普通组件一致。

放置后添加普通组件到布局组件内

        添加普通组件到布局组件内有两种方式:

        第一种:点击添加(选用先选中布局组件)

        怎么实现选中布局组件可以看前面的文章。选中后仓库state的selectedField为当前高亮的布局组件。

        点击添加普通组件,根据仓库里的selectedField判断是否当前选中了布局组件,如果选中,则往选中的布局组件里添加普通组件,如果没有选中的组件或者选中的组件不是布局组件,则按前面章节的点击添加组件生成默认布局属性进入到整体布局之中。

async handleClickAddField(type) {// 布局组件类型const limitType = [// 布局容器DashboardControlTypeEnum.Container,// 分页卡DashboardControlTypeEnum.Tabs,];// 创建普通组件let field = createDashboardField(type);// 当前选择了组件,且选择的组件是布局组件if (this.selectedField && limitType.includes(this.selectedField.type)) {// 新增的普通组件添加父组件属性field.parentId = this.selectedField.pkId;}...}

        上面的代码。只是判断了添加方式为往现有布局组件里添加了普通组件。

        我们先看看如果是嵌套布局(布局容器里有普通组件),此时的this.layout是什么样的?

        现在这个设计器里只有一个布局容器,布局容器里有一个普通组件

        此时this.layout只有一个元素。也就是说grid-layout不承认重叠关系。那么这个画中画是怎么实现的呢?

         也就是布局组件自己内部是个grid-layout,拖拽进去的普通组件被存储到布局组件自身属性上。设计器的grid-layout不关心布局组件内部有多少普通组件,也不关心布局组件内部普通组件怎么排列。

// 最外层布局的组件排列
var layoutFieleds = [// 布局组件{layout:{x:0,y:0,w:30,h:30},// 自身属性widget: {// 布局组件内的组件排列layoutFields: [layout:{x:0,y:0,w:10,h:10},....]}}
]

         那么布局组件的内部怎么实现,我们放到后面讲

         第二种:拖拽添加

        拖拽模型是这样:

// index.vue
<div><a-card><control-list :dragType.sync="dragType" @add="handleClickAddField" /></a-card><a-card :class="$style.main"><drag-container:dragType.sync="dragType"/></a-card>
</div>dragType = null;
// control-list.vue...<div :class="$style.list"><divv-for="control in group.list":key="control.type":draggable="true"@dragstart="handleDragStart(control.type)"@dragend="handleDragEnd"@click.stop="handleAdd(control)"><x-icon :type="control.icon" /><span>{{ control.label }}</span></div>
</div>handleDragStart(type) {this.$emit('update:dragType', type);}handleDragEnd() {this.$emit('update:dragType', null);}

        左边的组件栏拖拽事件只要关注抛出的dragType就行了(要么是空要么是拖拽过去的组件类型)

        index.vue负责把dragType传入到<drag-container>组件里。其他不理会。

// drag-container.vue
<grid-layout@dragover.native="handleDrag"@dragleave.native="handleDragLeave"@drop.native="handleDrop"><grid-itemv-for="layoutItem in layout":key="layoutItem.i"v-bind="getLayoutProps(layoutItem)"><component:is="getComponent(layoutItem)"v-bind="getComponentProps(layoutItem)"@inChildComponent="inChildComponent"/></grid-item>
</grid-layout>

        可以看到,拖拽到布局容器里也是在grid-layout层里处理,而不是gird-item层中特殊处理。

        要看gird-layout上三个drag事件之前,我们需要先搞懂一个叫isInChildCom属性的判断逻辑

// drag-container.vue
@Watch('dragType')
handleDragTypeChange(type) {this.isInChildCom = false; // 重新拖动需要重置...
}

        每次左侧组件栏成功触发/结束拖拽事件,drag-container里的isInChildCom属性就会初始化为false.

        普通组件:

        虽然vue-gird-layout里的item是不支持重叠的。 但是我们依然需要当拖拽组件进入普通组件里面,去emit inChildComponent事件,使drag-cpntainer里的isInChildCom为true。从而阻断后面的放置操作。

// 普通组件<div@dragenter="dragenter"@dragover="dragover"@dragleave="dragleave"@drop="drop">...</div>/** @name 进入-有效目标 **/dragenter() {this.$emit('inChildComponent', true);}dragleave(e) {this.$emit('inChildComponent', false);}

         布局组件:

         布局组件也一样。通过改变isInChildCom 的值为ture,让index.vue拦截拖拽事务。把添加组件的逻辑遗留在布局组件内部进行处理。

// 布局组件<div@dragenter="dragenter"@dragover="dragover"@dragleave="dragleave"@drop="drop">...</div>/** @name 进入-有效目标 **/dragenter() {// 当拖拽的组件是布局组件或无效组件时if (this.limited) this.$emit('inChildComponent', true);this.$emit('inChildComponent', true);}/** @name 离开-有效目标 **/dragleave(e) {if (this.limit) return;const rect = this.$el.getBoundingClientRect();const inside = rectContainPoint(rect, {x: e.clientX,y: e.clientY,});// 确认拖拽组件已经离开布局if (!inside) {this.$emit('inChildComponent', false);// 更新内部布局this.updateInside(e);}}drop(e) {if (this.limit) return...// 添加组件到布局组件内部属性}

             具体的实现请看最后一篇推文

放置后禁止拖拽布局组件到布局组件内

        上一节已经说到了,在布局组件内部的drop系列事件里通过limit去限制(limit的逻辑就是判断拖拽进来的是不是布局组件)。如果是的话,把isInChildCom改成true拦截index层处理,同时布局组件内部也通过limit拦截处理。

删除布局组件内的普通组件

        由布局组件内部控制。详情请最后一篇推文

相关文章:

讲讲项目里的仪表盘编辑器(三)布局组件

布局容器处理 看完前面两章的讲解&#xff0c;我们对仪表盘系统有了一个大概的理解。接着我们讲讲更深入的应用。 上文讲解的编辑器只是局限于平铺的组件集。而在编辑器中&#xff0c;还会有一种组件是布局容器。它允许其他组件拖拽进入在里面形成自己的一套布局。典型的有分页…...

Linux- 后台运行符、nohup、disown

& &在Unix-like的操作系统&#xff08;如Linux和macOS&#xff09;的shell中&#xff0c;特别是在Bash这样的shell中&#xff0c;经常用作后台运行符号。让我们深入了解一下其功能和用法。 &作为后台运行符号&#xff1a; 基本用法: 当我们在一个命令或者一组命令…...

开发过程教学——交友小程序

交友小程序 1. 我的基本信息2. 我的人脉2.1 我的关注2.2 我的粉丝 3. 我的视频4. 我的相册 特别注意&#xff1a;由于小程序分包限制2M以内&#xff0c;所以要注意图片和视频的处理。 1. 我的基本信息 数据库表&#xff1a; 我的基本信息我的登录退出记录我的登录状态&#x…...

正则表达式 Regular Expression学习

该文章内容为以下视频的学习笔记&#xff1a; 10分钟快速掌握正则表达式_哔哩哔哩_bilibili正则表达式在线测试工具&#xff1a;https://regex101.com/, 视频播放量 441829、弹幕量 1076、点赞数 19330、投硬币枚数 13662、收藏人数 26242、转发人数 2768, 视频作者 奇乐编程学…...

代谢组学最常用到的数据分析方法(五)

代谢组学是一门对某一生物或细胞所有低分子质量代谢产物&#xff08;以相对分子质量<1000的有机和无机的代谢物为研究核心区&#xff09;进行分析的新兴学科。因此从复杂的代谢组学数据中确定与所研究的现象有关的代谢物&#xff0c;筛选出候选生物标记物成为代谢物组学研究…...

105.从前序与中序遍历序列构造二叉树

力扣题目链接(opens new window) 根据一棵树的前序遍历与中序遍历构造二叉树。 注意: 你可以假设树中没有重复的元素。 例如&#xff0c;给出 前序遍历 preorder [3,9,20,15,7] 中序遍历 inorder [9,3,15,20,7] 返回如下的二叉树&#xff1a; class Solution { public:Tr…...

分支定界、分支切割、分支定价的区别

目录 1.从原理的角度 &#xff08;1&#xff09;分支定界&#xff1a; &#xff08;2&#xff09;分支切割&#xff1a; &#xff08;3&#xff09;分支定价&#xff1a; 2.从分支树的角度 &#xff08;1&#xff09;分支定界 &#xff08;2&#xff09;分支切割 &…...

数字IC前端学习笔记:数字乘法器的优化设计(阵列乘法器)

相关阅读 数字IC前端https://blog.csdn.net/weixin_45791458/category_12173698.html?spm1001.2014.3001.5482 数字信号处理作为微处理器的核心部件&#xff0c;是决定着总体处理器性能的因素之一&#xff0c;而数字乘法器是最常见的一种数字信号处理电路。通常情况下&#…...

批量删除wordpress文章修订版本/自动草稿残留数据(3种方法)及四种方法禁用WordPress文章历史修订/自动保存/自动草稿功能

目录 1、批量删除wordpress文章修订版本/自动草稿残留数据&#xff08;3种方法&#xff09; 方法一&#xff1a;SQL命令批量删除 命令&#xff1a; 方法二&#xff1a;利用PHP代码来删除 方法三&#xff1a;利用数据库清理优化插件 WP Clean Up 或 WP Cleaner 批量删除 2…...

HTTP初识,fiddler的使用,URL各部分介绍,QueryString

目录 一、什么是HTTP 二、抓包工具 三、请求的首行 URL 四、URL的各部分详细介绍 一、什么是HTTP 现在网页上&#xff0c;我们常见的是https,但是在二十年前是以http为主&#xff0c;这个协议也叫超文本传输协议&#xff0c;文本->字符串&#xff0c;“超文本”->图片…...

计算机毕业设计 基于SpringBoot的图书馆管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…...

第三章:最新版零基础学习 PYTHON 教程(第十二节 - Python 运算符—Python 中的运算符函数 - 套装1)

Python 在“operator”模块下预定义了许多数学、逻辑、关系、位等运算的函数。本文介绍了一些基本功能。 1. add(a, b):- 该函数返回给定参数的加法。 操作-a +b。 2. sub(a, b):- 该函数返回给定参数的差值。 操作-a -b。 3. mul(a, b):- 该函数返回给定参数的乘积。 操…...

AAD基础知识(identity/token/PRT)

简介 AAD(Azure Active Directory/Azure AD)是微软基于云身份验证和访问控制的解决方案&#xff0c;通过SSO登录其他o365应用(word/outlook/teams…) 微软在2023年7月把AAD重命名为Microsoft Entra ID&#xff0c;官网&#xff1a;https://www.microsoft.com/zh-cn/security/b…...

基于SSM的视频点播系统设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…...

React 知识点总结

本篇文章是我自己总结已经写过的react知识点&#xff0c;大框架已生成&#xff0c;知识持续更新中。仅供参考 生命周期 React 生命周期 组件基础 react中受控组件与非受控组件 React Portals 理解React页面渲染原理&#xff0c;如何优化React性能&#xff1f; 学习篇之R…...

ALSA project the C library refrerenc (ALSA工程 C库参考说明)

作者: Jaroslav Kysela perexperex.cz Abramo Bagnara abramoalsa-project.org Takashi Iwai tiwaisuse.de Frank van de Pol fvdpolcoil.demon.nl前言: 高级linux音频架构(ALSA)来自内核API和库的API.这个篇文章描述了应用层库API和内核层API对应是怎么的interfaces.API用法: …...

【Maven基础篇-黑马程序员】Maven项目管理从基础到高级,一次搞定!

文章目录 前言Maven简介Maven是什么Maven的作用 Maven的下载与安装Maven基础概念仓库坐标仓库配置全局setting与用户setting区别 第一个Maven程序&#xff08;手工制作&#xff09;第一个Maven程序&#xff08;IDEA生成&#xff09;使用模版&#xff08;骨架&#xff09;创建Ma…...

MySQL进阶 —— 超详细操作演示!!!(下)

MySQL进阶 —— 超详细操作演示&#xff01;&#xff01;&#xff01;&#xff08;下&#xff09; 五、锁5.1 概述5.2 全局锁5.3 表级锁5.4 行级锁 六、InnoDB 引擎6.1 逻辑存储结构6.2 架构6.3 事务原理6.4 MVCC 七、MySQL 管理7.1 系统数据库7.2 常用工具 MySQL— 基础语法大…...

SVM(上):如何用一根棍子将蓝红两色球分开?

⭐️⭐️⭐️⭐️⭐️欢迎来到我的博客⭐️⭐️⭐️⭐️⭐️ 🐴作者:秋无之地 🐴简介:CSDN爬虫、后端、大数据领域创作者。目前从事python爬虫、后端和大数据等相关工作,主要擅长领域有:爬虫、后端、大数据开发、数据分析等。 🐴欢迎小伙伴们点赞👍🏻、收藏⭐️、…...

libevent源码学习笔记

libevent源码学习笔记 libevent安装libevent源码解析&#xff08;1&#xff09;事件对象&#xff08;2&#xff09;事件操作&#xff08;3&#xff09;事件循环&#xff08;4&#xff09;事件处理 常用指令问题记录问题一&#xff1a;长连接的管理问题二&#xff1a;连接关闭问…...

避坑指南:Windows下OpenCV摄像头索引混乱问题的3种解决之道

避坑指南&#xff1a;Windows下OpenCV摄像头索引混乱问题的3种解决之道 在工业视觉和智能监控领域&#xff0c;多摄像头协同工作是常见需求。但当你在Windows平台上使用OpenCV的VideoCapture接口时&#xff0c;可能会遇到这样的困扰&#xff1a;每次重启系统后&#xff0c;原本…...

Java 设计模式・策略模式篇:从思想到代码实现

一、行为型模式 在面向对象的世界里&#xff0c;如何优雅地组织对象间的交互、分配职责&#xff0c;是每一位开发者都会反复思考的问题。直接硬编码交互逻辑固然简单&#xff0c;但当业务复杂度上升、对象协作关系变得错综复杂时&#xff0c;这种方式就会让代码变得僵化、难以…...

技术驱动B端拓客升级:号码核验行业的痛点突围与发展新路径,氪迹科技核验筛选算法系统,法人股东核验,阶梯式价格

在B端市场竞争愈发精细化的当下&#xff0c;拓客工作的核心竞争力已从“广撒网”转向“精准触达”&#xff0c;而企业核心决策人的有效联系方式&#xff0c;正是精准拓客的关键载体。号码核验作为拓客流程的前置核心环节&#xff0c;直接决定着拓客投入的回报效率&#xff0c;更…...

别光看原理了!用STM32F407从零撸一个四轴飞控代码(附完整工程)

用STM32F407从零构建四轴飞控代码实战指南 当你在论坛上看到别人分享的无人机飞行视频&#xff0c;是否也曾心动想亲手打造一套自己的飞控系统&#xff1f;市面上大多数教程止步于理论讲解&#xff0c;真正落实到代码层面的少之又少。本文将带你用STM32F407开发板&#xff0c;…...

OpenClaw技能扩展实战:基于Qwen3-32B开发自定义文件处理器

OpenClaw技能扩展实战&#xff1a;基于Qwen3-32B开发自定义文件处理器 1. 为什么需要自定义文件处理器 上周处理季度数据时&#xff0c;我又遇到了那个老问题&#xff1a;手头有37个CSV文件需要清洗格式、去重合并&#xff0c;还要按日期归档。这种重复性工作既耗时又容易出错…...

保研党必看:用本科论文逆袭IEEE二区期刊的5个关键操作(含时间管理秘籍)

保研党必看&#xff1a;用本科论文逆袭IEEE二区期刊的5个关键操作&#xff08;含时间管理秘籍&#xff09; 在保研竞争日益激烈的当下&#xff0c;一篇高质量的学术论文往往能成为决定成败的关键。对于大多数本科生来说&#xff0c;科研经历有限、资源匮乏是普遍面临的困境。但…...

Bitahub算力上新 RTX3080 10G重磅登场

针对当前 AI 开发与科研场景中算力成本高、配置复杂的痛点&#xff0c;Bitahub 平台推出了 RTX3080 10G 显卡算力服务。该显卡具备 10GB 显存&#xff0c;能够满足模型训练、推理等多场景算力需求&#xff0c;同时平台定价极具竞争力&#xff1a;单卡低至 0.82 元 / 小时&#…...

LangGraph实战:从零构建并部署一个多功能智能体

1. LangGraph框架概述&#xff1a;新一代智能体开发范式 在人工智能应用开发领域&#xff0c;智能体&#xff08;Agent&#xff09;技术正经历着从简单问答到复杂任务执行的进化。LangGraph作为LangChain生态中的新一代开发框架&#xff0c;彻底改变了传统链式结构的局限性。我…...

FPGA调试避坑指南:Vivado ILA采样深度和探针位宽怎么设?资源占用与调试效果的平衡术

FPGA调试实战&#xff1a;ILA采样深度与探针位宽的黄金平衡法则 当你在Artix-7芯片上调试一个包含32位计数器和多状态机的设计时&#xff0c;突然发现ILA吃掉了一半的Block RAM资源&#xff0c;而采样深度却只够捕获5个时钟周期的数据——这种场景是否似曾相识&#xff1f;本文…...

苹果全球推出关键MDM工具和企业服务

随着苹果在企业市场份额的稳步增长&#xff0c;该公司终于在美国以外地区推出了其面向中小型企业&#xff08;SMB&#xff09;的实用服务集合Apple Business Essentials&#xff0c;但这次它不再叫Apple Business Essentials&#xff0c;而且其中大部分服务都将免费提供。Apple…...