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

前端vue左侧树的一整套功能实现(一):vue2+vite封装v-resize指令,实现左侧树拖拽宽度和折叠展开

实现v-resize指令,具体以下功能:

  1. 指令接收宽度最大最小值,接收一个id用于localStorage存储拖拽宽度,接收padding
  2. 拖拽时产生虚线拖拽,松开鼠标再进行元素宽度调整
  3. 折叠展开图标使用本地图片

封装一个vite下使用本地图片的函数方法

用于拖拽指令中设置折叠展开图标

/** vite使用动态图片的方式 */
export function requireImg(name) {return new URL(`/src/assets/imgs/${name}`, import.meta.url).href
}

v-resize指令具体代码

// 注意,需要去除绑定元素的overflow:auto,指令会添加一个具有overflow:auto的元素
let resize;
let stopResize;
const vResize = {bind(el, binding) {// 从绑定值中获取最小宽度和最大宽度const {minWidth = 150,maxWidth = 400,id = '',padding = 10,} = binding.value || {};// 拖拽元素内部插入一个包裹元素,方便控制所有子元素隐藏显示const wrapper = document.createElement('div');wrapper.style.cssText = `width: 100%; height: 100%; overflow: auto; padding:${padding}px`;while (el.firstChild) {// appendChild 方法用于将一个节点添加到另一个节点的子节点列表的末尾。// 如果要添加的节点已经存在于文档树中,appendChild 方法会将该节点从其当前位置移动到新的位置,而不是复制该节点。// 这样就可以将 el 的所有子元素通过循环全部插入至 wrapper 中wrapper.appendChild(el.firstChild);}el.appendChild(wrapper);// 创建拖拽元素const resizer = document.createElement('div');resizer.style.cssText ='width: 10px; height: 100%; position: absolute; right: -10px; top: 0px; cursor: ew-resize; user-select: none; display: flex; justify-content: center; align-items: center; z-index: 999;';el.style.position = 'relative';el.style.padding = '0px';el.appendChild(resizer);el.style.transition = 'width 0.3s ease';// 缓存宽度const savedWidth = localStorage.getItem('WIDTH' + id);if (savedWidth) {el.style.width = savedWidth;if (el.style.width === '0px') {wrapper.style.display = 'none';}}// 创建切换按钮const img = document.createElement('img');img.src =el.style.width === '0px'? requireImg('tree/7.png'): requireImg('tree/6.png');img.style.cssText = 'cursor:pointer;height:40px;';resizer.appendChild(img);// 切换显示/隐藏逻辑img.addEventListener('mousedown', (e) => {e.stopPropagation();toggleContainer(el, wrapper, img);});// 拖拽虚线const line = document.createElement('div');line.style.cssText ='position: absolute; height: 100%; width: 2px; right: 0; top: 0; z-index: 9999; border-right: 0px dashed #409EFF; pointer-events: none;';el.appendChild(line);// 拖拽事件resizer.addEventListener('mousedown', () => {document.addEventListener('mousemove', resize);document.addEventListener('mouseup', stopResize);});let newWidth;resize = function (e) {line.style.borderRight = '2px dashed #409EFF';// 使用传入的最小宽度和最大宽度const width = e.pageX - el.getBoundingClientRect().left;if (width <= 0) {newWidth = 0;} else {newWidth = Math.max(minWidth, Math.min(maxWidth, width));}line.style.right = `${el.getBoundingClientRect().right - e.pageX}px`;};stopResize = function () {line.style.borderRight = '0px dashed #409EFF';document.removeEventListener('mousemove', resize);document.removeEventListener('mouseup', stopResize);if (newWidth) {el.style.width = `${newWidth}px`;setTimeout(() => {wrapper.style.display = 'block';}, 200);} else {el.style.width = `0px`;wrapper.style.display = 'none';}img.src =newWidth === 0 ? requireImg('tree/7.png') : requireImg('tree/6.png');localStorage.setItem('WIDTH' + id, el.style.width);};function toggleContainer(el, wrapper, img) {if (el.style.width === '0px') {el.style.width = `${minWidth}px`;img.src = requireImg('tree/6.png');setTimeout(() => {wrapper.style.display = 'block';}, 200);} else {wrapper.style.display = 'none';el.style.width = '0px';img.src = requireImg('tree/7.png');}localStorage.setItem('WIDTH' + id, el.style.width);}},unbind() {// 清除所有事件监听器,防止内存泄漏document.removeEventListener('mousemove', resize);document.removeEventListener('mouseup', stopResize);},
};Vue.directive('resize', vResize);

使用指令

 <div class="page"><divclass="left"v-resize="{id: 'left_tree',minWidth: '473',maxWidth: '773',}"v-loading="treeloading">...</div><div class="right">...</div></div>
.page{display:flex;.left_tree{width:550px;}.right{flex:1;}
}

相关文章:

前端vue左侧树的一整套功能实现(一):vue2+vite封装v-resize指令,实现左侧树拖拽宽度和折叠展开

实现v-resize指令&#xff0c;具体以下功能&#xff1a; 指令接收宽度最大最小值&#xff0c;接收一个id用于localStorage存储拖拽宽度&#xff0c;接收padding拖拽时产生虚线拖拽&#xff0c;松开鼠标再进行元素宽度调整折叠展开图标使用本地图片 封装一个vite下使用本地图片…...

本地部署huggingface模型,建立自己的翻译应用

过去&#xff0c;我们使用翻译接口时&#xff0c;往往都是使用百度等的接口&#xff0c;每天有一定量的免费额度。今天为大家介绍一个可以进行翻译的模型&#xff0c;具备英译中、中译英的能力。并且在这个过程中&#xff0c;向大家介绍一个如何在本地部署模型。在之前的”五天…...

基于python+django+vue的在线学习资源推送系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于协同过滤pythondjangovue…...

.Net Gacutil工具(全局程序集缓存工具)使用教程

GAC介绍&#xff1a; GAC&#xff08;Global Assembly Cache&#xff09;全局程序集缓存&#xff0c;是用于存放.Net应用程序共享的程序集。 像平常我们在Visual Studio中引用系统程序集时&#xff0c;这些程序集便来自于GAC。 GAC默认位置为&#xff1a;%windir%\Microsoft…...

安卓13修改设置设备型号和设备名称分析与更改-android13设置设备型号和设备名称更改

总纲 android13 rom 开发总纲说明 文章目录 1.前言2.问题分析3.代码分析4.代码修改5.编译6.彩蛋1.前言 用户要定制一些系统显示的设备型号和设备名称,这就需要我们分析设置里面的相关信息来找到对应的位置进行修改了。 2.问题分析 像这种信息要么是config.xml里面写死了,要…...

AI健身体能测试之基于paddlehub实现引体向上计数个数统计

【引体向上计数】 本项目使用PaddleHub中的骨骼检测模型human_pose_estimation_resnet50_mpii&#xff0c;进行人体运动分析&#xff0c;实现对引体向上的自动计数。 1. 项目介绍 人体运动分析是近几年许多领域研究的热点问题。在学科的交叉研究上&#xff0c;人体运动分析涉…...

Redis常见报错及解决方法总结

Redis常见报错及解决方法总结 Redis作为高效的内存数据库&#xff0c;在实际使用过程中不可避免会遇到一些问题和报错。为了帮助大家更好地应对这些问题&#xff0c;我将常见的Redis报错及其解决方法进行总结&#xff0c;并提供具体的操作步骤。 1. Connection Refused 错误…...

【TabBar嵌套Navigation案例-JSON的简单使用 Objective-C语言】

一、JSON的简单使用 1.我们先来看一下示例程序里边,产品推荐页面, 在我们这个产品推荐页面里面, 它是一个CollectionViewController,注册的是一个xib的一个类型,xib显示这个cell,叫做item,然后,这个邮箱大师啊,包括这个图标,以及这些东西,都是从哪儿来的呢,都是从…...

通过鼠标移动来调整两个盒子的宽度(响应式)

DOM结构&#xff1a; <div class"courer"> // 外层盒子<div class"dividing-line" title"拖动"></div> // 拖动的那个线<div class"course-title-box"> // 第一个盒子<div class"course-content-…...

React Zustand状态管理库的使用

Zustand 是一个轻量级的状态管理库&#xff0c;适用于 React 和浏览器环境中的状态管理需求。它由 Vercel 开发并维护&#xff0c;旨在提供一种简单的方式来管理和共享状态。Zustand 的设计理念是尽可能简化状态管理&#xff0c;使其更加直观和易于使用。 Zustand 官网点击跳转…...

pyrosetta MoveMap介绍

在 PyRosetta 中,MoveMap 是一个非常重要的类,用来控制蛋白质分子中哪些部分可以在某些操作(如折叠、旋转、优化等)中被移动。MoveMap 允许你精确地指定哪些残基、键角或原子可以进行特定的运动,从而帮助你在蛋白质结构预测、优化和设计中进行灵活的控制。 MoveMap 的功能…...

在线安全干货|如何更改IP地址?

更改IP地址是一个常见的需求&#xff0c;无论是为了保护个人隐私、绕过地理限制还是进行商业数据分析。不同的IP更改方法适用于不同的需求和环境。但请注意&#xff0c;更改IP地址应在合法场景下进行&#xff0c;无论使用什么方法&#xff0c;都需要在符合当地网络安全法律法规…...

【C++】【网络】【Linux系统编程】单例模式,加锁封装TCP/IP协议套接字

目录 引言 获取套接字 绑定套接字 表明允许监听 单例模式设计 完整代码示例 个人主页&#xff1a;东洛的克莱斯韦克-CSDN博客 引言 有关套接字编程的细节和更多的系统调用课参考《UNIX环境高级编程》一书&#xff0c;可以在如下网站搜索电子版&#xff0c;该书在第16章详…...

Matplotlib在运维开发中的应用

在现代运维开发中,数据可视化扮演着越来越重要的角色。它能帮助我们更直观地理解系统状态,快速发现潜在问题,并辅助决策制定。Python的Matplotlib库作为一个强大而灵活的绘图工具,在运维领域有着广泛的应用。本文将探讨Matplotlib在运维开发中的常见应用场景,并提供实用的代码示…...

centos下nvme over rdma 环境配置

nvme over rdma 环境配置 本文主要介绍NVMe over RDMA的安装和配置。关于什么是NVMe over Fabrics,什么是NVMe over RDMA&#xff0c;本文就不做介绍了&#xff0c;网上资料一大堆。 可以看看什么是NVMe over Fabrics&#xff1f; RDMA&#xff08;全称&#xff1a;Remote Dir…...

【C++】——多态详解

目录 1、什么是多态&#xff1f; 2、多态的定义及实现 2.1多态的构成条件 ​2.2多态语法细节处理 2.3协变 2.4析构函数的重写 2.5C11 override 和 final关键字 2.6重载—重写—隐藏的对比分析 3、纯虚函数和抽象类 4、多态的原理分析 4.1多态是如何实现的 4.2虚函数…...

STM32上实现FFT算法精准测量正弦波信号的幅值、频率和相位差(标准库)

在研究声音、电力或任何形式的波形时&#xff0c;我们常常需要穿过表面看本质。FFT&#xff08;快速傅里叶变换&#xff09;就是这样一种强大的工具&#xff0c;它能够揭示隐藏在复杂信号背后的频率成分。本文将带你走进FFT的世界&#xff0c;了解它是如何将时域信号转化为频域…...

计算机毕业设计 农场投入品运营管理系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…...

【笔记】2.1 半导体三极管(BJT,Bipolar Junction Transistor)

一、结构和符号 1. 三极管结构 常用的三极管的结构有硅平面管和锗合金管两种类型。各有PNP型和NPN型两种结构。 左图是NPN型硅平面三极管,右图是PNP型锗合金三极管。 从图中可见平面型三极管是先在一块大的金属板上注入杂质使之变成N型,然后再在中间注入杂质使之变成P型,…...

企业中文档团队的三种组织形式

大家好&#xff01;今天咱们来聊聊企业里文档团队都是怎么组织的。 企业中&#xff0c;常见的文档团队组织形式有三种。 首先&#xff0c;最常见的就是集中式的文档团队。就是说&#xff0c;公司里头有几个不同的部门&#xff0c;每个部门都需要做文档。于是呢&#xff0c;公…...

遥感影像语义分割数据集全景解析:从经典基准到前沿应用

1. 遥感影像语义分割入门指南 第一次接触遥感影像语义分割时&#xff0c;我被那些五彩斑斓的土地分类图深深吸引。简单来说&#xff0c;这就像给地球表面拍X光片——不同颜色代表不同地物类型&#xff0c;比如蓝色是水域&#xff0c;绿色是植被&#xff0c;红色是建筑。这种技术…...

比较器参数实测对比:LM393 vs LM311 vs MAX902(附测试数据)

比较器参数实测对比&#xff1a;LM393 vs LM311 vs MAX902&#xff08;附测试数据&#xff09; 在电子设计领域&#xff0c;比较器作为信号处理的关键元件&#xff0c;其性能直接影响系统的响应速度和精度。面对市面上琳琅满目的比较器型号&#xff0c;工程师们常常陷入选择困境…...

NE555芯片应用与15个经典电路项目详解

1. NE555芯片&#xff1a;电子工程师的瑞士军刀NE555这颗小小的8脚芯片&#xff0c;自1971年由Signetics公司推出以来&#xff0c;已经陪伴电子工程师走过了半个世纪。它就像电子设计领域的瑞士军刀&#xff0c;凭借其稳定的定时精度、灵活的配置方式和低廉的价格&#xff0c;至…...

OpenClaw+gemma-3-12b-it:多语言文档自动翻译系统

OpenClawgemma-3-12b-it&#xff1a;多语言文档自动翻译系统 1. 为什么需要本地化文档翻译方案 去年参与一个跨国协作项目时&#xff0c;我每天要处理数十份英文技术文档。传统翻译工具要么需要手动复制粘贴&#xff0c;要么存在隐私泄露风险。直到发现OpenClawgemma-3-12b-i…...

MQ2_LPG气体检测库:嵌入式LPG泄漏监测与动态校准实践

1. MQ2_LPG气体检测库深度解析&#xff1a;面向嵌入式系统的LPG泄漏监测工程实践 1.1 库定位与工程价值 MQ2_LPG是一个专为嵌入式平台设计的轻量级气体传感驱动库&#xff0c;核心目标是实现对液化石油气&#xff08;Liquefied Petroleum Gas, LPG&#xff09;中丙烷&#xff…...

基于springboot+vue大学生租房平台hx0096FFZC

文章目录详细视频演示技术介绍功能介绍核心代码系统效果图源码获取详细视频演示 文章底部名片&#xff0c;获取项目的完整演示视频&#xff0c;免费解答技术疑问 技术介绍 开发语言&#xff1a;Java 框架&#xff1a;ssm JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomca…...

OpenClaw多模型切换指南:Qwen3-4B与本地LLM混合调用

OpenClaw多模型切换指南&#xff1a;Qwen3-4B与本地LLM混合调用 1. 为什么需要多模型混合调用 去年冬天&#xff0c;当我第一次尝试用OpenClaw自动化处理技术文档时&#xff0c;发现一个尴尬的现象&#xff1a;用Qwen3-4B生成代码示例效果很好&#xff0c;但让它润色一段产品…...

微信小程序使用websocket调用大模型返回逐字显示的结果

页面展示&#xff1a;小程序代码&#xff1a; aichat.js:const config require(../../utils/config.js); Page({data: {messages: [],inputText: ,isLoading: false,scrollToId: scroll-bottom,currentStreamingId: null,isConnecting: false,isReceiving: false,socketOpen: …...

DL基础营 | 第P1周:Pytorch实现mnist手写数字识别

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊编译器&#xff1a;jupyterlab 一、 前期准备 1. 设置GPU 2. 导入数据 3. 数据可视化 二、构建简单的CNN网络 加载并打印模型 三、 训练模型 1. 设置超参数 …...

yaml-cpp终极内存优化指南:5个提升缓存命中率的实现技巧

yaml-cpp终极内存优化指南&#xff1a;5个提升缓存命中率的实现技巧 【免费下载链接】yaml-cpp A YAML parser and emitter in C 项目地址: https://gitcode.com/gh_mirrors/ya/yaml-cpp yaml-cpp是一个高性能的C YAML解析器和发射器&#xff0c;完全遵循YAML 1.2规范。…...