Vue3拖拽修改左侧元素宽度组件开发

       在开发过程中有时候会碰到需要拖拽修改页面元素宽度的需求,实际场景是页面上有并排两个或多个元素,需要拖拽修改其中一个元素的宽度,则只引入下方组件代替页面中需要被拖拽的元素及右侧相邻的元素。需要将需要拖拽的元素放进下面组件的左边的插槽中,右侧相邻的元素放入下方组件右侧的插槽中即可。

<template><!-- 左侧元素 --><el-asideref="leftAsideRef"class="container__left border-right"width="260px"@mousemove="handleMousemove"@mousedown="handleMousedown"@mouseup="handleMouseup"><slot name="left"></slot></el-aside><!-- 右侧元素 --><el-asideref="rightAsideRef"class="container__middle border-right"width="260px"@mousemove="handleMousemove"@mousedown="handleMousedown"@mouseup="handleMouseup"><slot name="right"></slot></el-aside>
</template><script lang="ts">
import { defineComponent, reactive, toRefs, ref, watch } from 'vue';export default defineComponent({name: 'DragChangeLeftWidth',props: {// 是否隐藏左边的元素hiddenLeft: {type: Boolean,default: false,},// 左侧元素可拖拽的最小宽度minWidth: {type: Number || String,default: 200,},// 左侧元素可拖拽的最大宽度maxWidth: {type: Number || String,default: 900,},},setup(props, { emit }) {const state = reactive({// 第一把锁控制鼠标形状改变resizableLock1: false,// 第二把锁控制是否可以拖拽resizableLock2: false,// 拖拽之前起始x坐标initialX: 0,// 拖拽之前起始宽度initialWidth: 0,});// 左侧domRefconst leftAsideRef = ref();// 右侧aside domRefconst rightAsideRef = ref();/*** @description: 左侧指标模块鼠标进入事件* @return {*}*/const handleMousemove = (e: any) => {// 现获取左侧dom 的左侧x轴坐标const rightXAxis = leftAsideRef.value?.$el.getBoundingClientRect()?.right;const leftXAxis = leftAsideRef.value?.$el.getBoundingClientRect()?.left;// 获取当前鼠标所在x轴的坐标const mouseXAxis = e.clientX;// 当鼠标从dom右侧进入5px距离之间时,修改鼠标样式if ((rightXAxis >= mouseXAxis && rightXAxis - mouseXAxis <= 10)|| (rightXAxis < mouseXAxis && mouseXAxis - rightXAxis <= 10)) {if (!state.resizableLock2) {// 只能先开启第一把锁state.resizableLock1 = true;}} else if (!state.resizableLock2) {// 将鼠标形状复原// 第二把锁不关第一把锁不能关state.resizableLock1 = false;}// 第一把锁控制鼠标变形if (state.resizableLock1) {leftAsideRef.value.$el.style.cursor = 'w-resize';rightAsideRef.value.$el.style.cursor = 'w-resize';// 打开第一把锁之后,要将fixed-container子元素设置pointer-event:noneconst leftChildList = leftAsideRef.value.$el.children;leftChildList.forEach((item: any) => {// eslint-disable-next-line no-param-reassignitem.style.pointerEvents = 'none';});const rightChildList = rightAsideRef.value.$el.children;rightChildList.forEach((item: any) => {// eslint-disable-next-line no-param-reassignitem.style.pointerEvents = 'none';});} else {leftAsideRef.value.$el.style.cursor = 'default';rightAsideRef.value.$el.style.cursor = 'default';// 第一把锁关闭之后,要将fixed-container子元素设置pointer-event:autoconst leftChildList = leftAsideRef.value.$el.children;leftChildList.forEach((item: any) => {// eslint-disable-next-line no-param-reassignitem.style.pointerEvents = 'auto';});const rightChildList = rightAsideRef.value.$el.children;rightChildList.forEach((item: any) => {// eslint-disable-next-line no-param-reassignitem.style.pointerEvents = 'auto';});}if (state.resizableLock2) {// 只有当可以进行拖拽的时候,才去清除鼠标默认事件e.preventDefault();// 第二把锁控制移动const updateWidth = e.clientX - state.initialX;// 超出最小值范围则不进行修改宽度操作,但是要更新初始宽度和初始x坐标if (rightXAxis - leftXAxis <= props.minWidth && updateWidth < 0) {state.initialX = e.clientX;state.initialWidth = leftAsideRef.value.$el.offsetWidth;return;}if (rightXAxis - leftXAxis >= props.maxWidth && updateWidth > 0) {state.initialX = e.clientX;state.initialWidth = leftAsideRef.value.$el.offsetWidth;return;}const newWidth = state.initialWidth + updateWidth;leftAsideRef.value.$el.style.width = `${newWidth}px`;}};/*** @description: 监听鼠标按下事件* @return {*}*/const handleMousedown = (e: any) => {if (state.resizableLock1) {// 只有当可以进行拖拽的时候,才去清除鼠标默认事件e.preventDefault();// 只有当第一把锁打开的时候,才能打开第二把锁state.resizableLock2 = true;}state.initialX = e.clientX;state.initialWidth = leftAsideRef.value.$el.offsetWidth;};/*** @description: 鼠标回弹触发事件* @return {*}*/const handleMouseup = () => {state.resizableLock2 = false;state.resizableLock1 = false;};return {...toRefs(state),leftAsideRef,rightAsideRef,handleTransitionend,handleMousemove,handleMousedown,handleMouseup,};},
});
</script>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/841807.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pdf拆分成多个文件 pdf拆分成一页一页

pdf拆分成多个文件的方法。在现代办公环境中&#xff0c;PDF文件因其跨平台、保持格式一致等特性&#xff0c;成为了广泛使用的文件格式。然而&#xff0c;有时我们需要对PDF文件进行拆分&#xff0c;以便更好地管理和使用其中的内容。本文将详细介绍PDF拆分的方法和步骤&#…

Flutter 中的 ClipOval 小部件:全面指南

Flutter 中的 ClipOval 小部件&#xff1a;全面指南 在Flutter的丰富布局库中&#xff0c;ClipOval是一个用于裁剪子组件的显示区域为椭圆形或圆形的小部件。这种裁剪效果可以用于创建头像、图标或其他图形元素的美观边框。本文将提供ClipOval的全面指南&#xff0c;帮助你了解…

一.架构设计

架构采用 ddd 架构&#xff0c;不同于传统简单的三层的架构&#xff0c;其分层的思想对于大家日后都是很有好处的&#xff0c;会给大家的思想层级&#xff0c;提高很多。 传统的项目 现有的架构 采取ddd架构&#xff0c;给大家在复杂基础上简化保留精髓&#xff0c;一步步进行…

LabVIEW直方图应用解析

概述 在LabVIEW中&#xff0c;直方图是一种重要的工具&#xff0c;用于分析和展示数据的分布情况。它通过将数据分成若干区间并绘制对应频数&#xff0c;可以帮助用户了解数据的集中趋势、离散程度和分布形态。本文将详细介绍LabVIEW中直方图的使用方法、适用场合、实际意义及…

19 QinQ技术(Vlan两层封装)

1 什么是QinQ&#xff1f; QinQ&#xff08;802.1Q-in-802.1Q&#xff09;&#xff0c;也叫做VLAN Stacking或Double VLAN&#xff0c;由IEEE 802.1ad标准定义&#xff0c;**是一项扩展VLAN空间的技术&#xff0c;**通过在802.1Q标签报文的基础上再增加一层802.1Q的Tag来达到扩…

工具使用-网络性能测试工具(iperf)-TCP 和 UDP 的吞吐量-包转发率参数的理解

时间戳&#xff1a;2024年5月26日15:18:39 iperf 和 netperf 都是最常用的网络性能测试工具&#xff0c;测试 TCP 和 UDP 的吞吐量。它们都以客户端和服务器通信的方式&#xff0c;测试一段时间内的平均吞吐量。 接下来&#xff0c;我们就以 iperf 为例&#xff0c;看一下 TC…

MyBatis进阶(<if><trim><where><set><foreach><include>标签的使用)

目录 < if >标签 < trim >标签 < where >标签 < set >标签 < foreach >标签 < include >标签 < if >标签 非必填字段 xml实现 <insert id"insertUserByCondition">INSERT INTO userinfo (username,passwor…

【力扣一轮】202.快乐数 1.两数之和

202.快乐数 力扣链接 代码随想录链接 思路 看到这一题没思路&#xff0c;直接看题解。 发现其中一个难点在于“无限循环”&#xff0c;这个字眼可以转换成退出条件。退出条件就有两种&#xff0c;一种是这个数字是快乐数&#xff0c;一种是这个数字不是快乐数。 如果是快…

【vue嵌套iframe】实现项目重构

vue嵌套iframe 创建 iframe 通用组件添加页面及路由进阶&#xff1a;vue 与 iframe 的双向通讯代码下载 适用于使用vue重构及vue访问其他服务页面 基于vue3示例页面添加嵌套iframe的页面 创建 iframe 通用组件 IframeTemplate.vue 页面布局 <template><div class…

9.2 Go语言入门(包和导入)

Go语言入门&#xff08;包和导入&#xff09; 目录一、包和导入1. 包&#xff08;Package&#xff09;1.1 包的定义1.2 包的作用1.3 main 包1.4 非 main 包 2. 导入&#xff08;Import&#xff09;2.1 导入标准库2.2 导入第三方包2.3 导入本地包2.4 导入别名2.5 导入并调用初始…

mysql授权用户

mysql授权用户只能看到某张表单表 要实现MySQL中的用户只能看到某张表&#xff0c;可以通过创建一个新的数据库用户&#xff0c;并且只授予该用户对特定表的权限。以下是实现这一功能的步骤和示例代码&#xff1a; 创建新用户并设置密码。 授予该用户对特定数据库的权限。 授…

国内最受欢迎的7大API供应平台对比和介绍||电商API数据采集接口简要说明

本文将介绍7款API供应平台&#xff1a;聚合数据、百度APIStore、Apix、数说聚合、通联数据、HaoService、datasift 。排名不分先后&#xff01; 免费实用的API接口 第一部分 1、聚合数据&#xff08;API数据接口_开发者数据定制&#xff09; 2、百度API Store(API集市_APIStore…

数据库系统原理实验报告6 | 视图

整理自博主本科《数据库系统原理》专业课自己完成的实验报告&#xff0c;以便各位学习数据库系统概论的小伙伴们参考、学习。 专业课本&#xff1a; ​ ———— 本次实验使用到的图形化工具&#xff1a;Heidisql ​ 目录 一、实验目的 二、实验内容 1&#xff0e;根据EDUC数…

妙解设计模式之适配器模式

适配器模式的概念 适配器模式是一种结构设计模式&#xff0c;它允许将接口不兼容的类通过一个适配器类进行适配&#xff0c;使得这些类可以一起工作。适配器模式通常用于以下情况&#xff1a; 当一个接口的实现类已经存在&#xff0c;但是另一个接口需要的是不兼容的时候。当…

揭秘C++ String容器:字符串操作的艺术

目录 ​编辑 引言 一、初识std::string&#xff1a;构造与初始化 二、字符串的操纵艺术&#xff1a;拼接、查找与替换 三、访问与遍历&#xff1a;字符的细腻触感 四、大小与容量&#xff1a;动态调整的智慧 五、进阶功能&#xff1a;探索更多可能 结语 引言 在C标准库…

ssms执行建表后如何自动刷新所有SQL SERVER表

在 SQL Server Management Studio (SSMS) 中&#xff0c;当你通过 T-SQL 脚本创建表后&#xff0c;通常需要手动刷新对象资源管理器以查看新表。SSMS 并没有提供自动刷新的选项&#xff0c;但你可以使用以下几种方法来解决这个问题&#xff1a; 手动刷新&#xff1a;在对象资源…

网络工程师基础知识:

网络工程师基础知识&#xff1a; 1.最基本的7层协议&#xff1a; 来源&#xff1a; 通过网络网线和报文的这些机制让全世界的数据通过二进制流来进行沟通 从下而上&#xff1a; 物理层 数据链路层 网络层 传输层 表示层 会话层 应用层 基本的一个数据报文&#xff1a; 数据链…

Java 8

这次我学习了第八次Java课程 这次课在假期&#xff0c;包含了两天的一大波内容 对于编写项目过程中有许多的 辅助类 System System.out.println() 打印 Scanner Scanner sc new Scanner(System.in) 赋值 Random 随机数 Math 数学运算 日期 要想使用日期方法就要引入包Date 1…

人工智能为犯罪地下世界带来了巨大的生产力提升

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

Java 18 新特性详解

Java 18 新特性详解 Java 18 作为 Oracle 推出的又一重要版本&#xff0c;继续秉持着 Java 平台“创新但不破坏”的原则&#xff0c;带来了多项旨在提升开发效率、性能和安全性的新特性。本篇文章将深入解析 Java 18 引入的主要特性&#xff0c;并探讨它们如何影响开发者的工作…