当前位置: 首页 > 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;公…...

Unity-MCP协议:可嵌入、可协商的AI上下文通信标准

1. 这不是又一个“AI插件”&#xff0c;而是Unity开发工作流的底层重定义你有没有过这样的时刻&#xff1a;在Unity里反复调整Animator Controller的过渡条件&#xff0c;只为让角色转身动画不穿模&#xff1b;写完一段NavMesh寻路逻辑&#xff0c;却要花两小时调试Agent卡在斜…...

Sora 2原生接入Unity 6.0:5步完成神经渲染管线嵌入,实测帧率提升47%(附GitHub认证插件)

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;Sora 2与Unity整合 Sora 2作为新一代AI视频生成引擎&#xff0c;其开放API设计天然支持与实时3D引擎的深度协同。Unity 2023.2版本通过URP&#xff08;Universal Render Pipeline&#xff09;与C# Job System提…...

Mysql:事务管理(中)

在前面的章节中&#xff0c;我们提到了 MVCC&#xff08;多版本并发控制&#xff09;&#xff0c;它巧妙地通过“版本快照”解决了“读-写”冲突&#xff0c;实现了非阻塞读。但如果两个事务同时执行 UPDATE 操作修改同一行数据&#xff0c;即 写-写&#xff08;Write-Write&am…...

2026长沙智能家居品牌实测,这些本地老牌值得选

2026年&#xff0c;长沙的智能家居市场已经从“概念热”转向“落地战”。我走访了长沙多个本地服务商&#xff0c;实测了不同品牌在别墅、酒店、大平层等场景的真实表现。今天&#xff0c;结合数据与案例&#xff0c;分享几个值得关注的本地品牌&#xff0c;尤其是深耕8年以上的…...

用Azure Kinect DK和Body Tracking SDK,5分钟实现一个实时人体骨骼点检测Demo(C++版)

5分钟实战&#xff1a;用Azure Kinect DK实现实时人体骨骼点追踪&#xff08;C版&#xff09; 当你第一次拿到Azure Kinect DK时&#xff0c;最令人兴奋的莫过于它强大的人体追踪能力。这款深度相机不仅能捕捉高清彩色图像&#xff0c;更能通过AI算法实时重建人体骨骼关节点。本…...

【DeepSeek灰度发布黄金法则】:20年SRE亲授7步零故障上线实战框架

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;DeepSeek灰度发布策略全景图 DeepSeek模型服务的灰度发布并非简单的流量切分&#xff0c;而是一套融合可观测性、渐进式验证与多维熔断机制的工程化闭环体系。其核心目标是在保障线上推理稳定性的同时&…...

LPCM框架:大模型驱动的计算机架构设计革命

1. LPCM框架&#xff1a;计算机系统架构设计的范式革命计算机系统架构设计正站在历史性的转折点上。过去八十年来&#xff0c;从ENIAC的真空管到现代7纳米制程的异构计算芯片&#xff0c;架构设计始终遵循着"专家经验EDA工具"的传统范式。但随着摩尔定律逼近物理极限…...

机器学习在犬类癌症筛查中的性能极限与挑战:基于血液数据的多癌种分析

1. 项目概述&#xff1a;当机器学习遇见犬类癌症筛查作为一名长期关注数据科学在生命科学领域应用的从业者&#xff0c;我常常被问及一个充满希望的问题&#xff1a;我们能否像分析人类健康数据一样&#xff0c;利用宠物的常规体检数据&#xff0c;通过机器学习提前发现癌症的蛛…...

为什么你的Midjourney雾效总像“水汽”而非“山岚”?——资深CG总监拆解大气散射物理模型在--v 6.1中的3层映射偏差

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;为什么你的Midjourney雾效总像“水汽”而非“山岚”&#xff1f; Midjourney 生成的雾气常呈现为均匀、半透明、边界模糊的“水汽感”——厚重、潮湿、缺乏层次与呼吸感。这并非模型能力不足&#xff0c;而是提…...

Unity中实现深度遮挡:LingBot-Depth实战接入与优化

1. 这不是“加个插件就完事”的AR效果——为什么LingBot-Depth在Unity里值得专门写一篇实战教程你肯定见过那种AR应用&#xff1a;虚拟椅子摆在真实地板上&#xff0c;但当你绕到椅子后面&#xff0c;它依然完整显示&#xff0c;完全无视身后那堵真实的墙&#xff1b;或者一只3…...