封装React组件DragLine,鼠标拖拽的边框改变元素宽度

简介: 封装React组件DragLine,鼠标拖拽的边框改变元素宽度

原文合集地址如下,有需要的朋友可以关注

本文地址

合集地址

在项目中,设计说想做个面板,其宽度随鼠标拖拽而变化,有最大最小值。基于这个小功能封装一个可拖拽组件,在需要的地方引入即可。

思路

这里只是实现x方向的拖拽,y轴拖拽思路差不多。
既然是鼠标操作,那肯定得监听鼠标事件,当鼠标按下(mouseDown)时,监听mouseMove事件和mouseUp事件,就是鼠标移动和抬起操作。然后计算出鼠标移动的宽度 = 元素现在的x坐标(clientX) - 起始坐标;然后把移动的宽度通过onChange函数返回给父组件,父组件改变自身的宽度。

代码示例

组件代码如下:

import React, {
    useRef, useState, useEffect } from 'react';
interface DragLineProps {
   
  style?: any; // 自定义样式
  className?: string; // 样式类名
  onChange: (width: number, height:number) => void; // 宽高变化函数
}

const DragLine: React.FC<DragLineProps> = (props) => {
   
  const {
   style, className, onChange } = props;
  const containerRef = useRef<HTMLDivElement>(null);
  const [isDragging, setIsDragging] = useState(false);
  const initialMouseX = useRef(0); // 初始x值
  const initialMouseY = useRef(0); // 初始Y值

  useEffect(() => {
   
    const handleMouseMove = (event: MouseEvent) => {
   
      if (isDragging && containerRef.current) {
   
        const deltaX = event.clientX - initialMouseX?.current;
        const deltaY = event.clientY - initialMouseY?.current;
        // 调用父组件函数,传回移动的宽度或高度
        onChange(deltaX, deltaY)
      }
    };

    const handleMouseUp = () => {
   
      setIsDragging(false);
    };
    // 添加鼠标移动和抬起事件
    document.addEventListener('mousemove', handleMouseMove);
    document.addEventListener('mouseup', handleMouseUp);

    return () => {
   
    // 记得清除监听事件
      document.removeEventListener('mousemove', handleMouseMove);
      document.removeEventListener('mouseup', handleMouseUp);
    };
  }, [isDragging, initialMouseX, initialMouseY, onChange]);

/** 监听鼠标按下事件 改变初始值 **/
  const handleMouseDown = (event: React.MouseEvent<HTMLDivElement>) => {
   
    event.preventDefault();
    setIsDragging(true);
     initialMouseX.current = event.clientX;
     initialMouseY.current =  event.clientY;
  };


  return (
    <div
      ref={
   containerRef}
      className={
   className} 
      style={
   style}
      onMouseDown={
   handleMouseDown}
    />
  );

};

export default DragLine;

使用:
我这里是左侧面板可拖拽宽度,当然也可以是右侧面板,如需上下拖动,可以先定义高度,然后通过子组件调用handleChange传回的offsetY操作即可。

import React, {
    useState } from 'react';
import DragLine from '../../components/DragBox';
import './style.less';
const maxWidth = 300;
const minWidth = 100;
const App: React.FC = () => {
   
  const [width, setWidth] = useState(200);

  const handleChange = (offsetX: number, offsetY:number) => {
   
    const current = offsetX+ width;
    const newWidth = current > maxWidth ? maxWidth : current < minWidth ? minWidth : current;
    setWidth(newWidth);
  };

  return (
    <div className='DragWrapperRoot'>
      <div style={
   {
   width}} className='dragBox'> 
          拖拽右侧边框改变盒子大小
      </div>
      <DragLine onChange={
   handleChange} className="width-drag" style={
   {
   left: width}}/>
    </div>
  );
};

export default App;

less文件:

.DragWrapperRoot{
   
  position: relative;
  display: flex;
  height: 80%;

  .dragBox{
   
    position: relative;
    border-right: 1px solid #999;
    height: 100%;
  }
  .width-drag{
   
    position: absolute; 
    cursor: ew-resize;  // 鼠标悬停双箭头样式
    top: 0;
    bottom: 0;
    width: 10px;
    background: transparent;
  }
}

总结

  1. 创建一个DragLine组件,接受一个onChange函数作为参数,该函数用于接收拖拽宽度的更新。
  2. 使用useRef钩子来获取<div>容器的引用,以便后续操作。
  3. 使用useState钩子来追踪拖拽状态,通过isDragging变量表示是否正在拖拽。
  4. 使用useEffect钩子来添加事件监听器,以便在鼠标移动和释放的过程中执行相应的操作。
  5. handleMouseMove回调函数中,根据鼠标位置和容器的左边界计算新的宽度和高度,并通过onChange函数将新的宽度传递给父组件。
  6. handleMouseUp回调函数中,将拖拽状态设置为false,表示拖拽结束。
  7. handleMouseDown回调函数中,将拖拽状态设置为true,表示开始拖拽。
  8. handleMouseDown函数绑定到容器的onMouseDown事件上,以便在鼠标按下时触发拖拽行为。
  9. 在组件的返回部分,使用ref将容器的引用与<div>元素关联起来。
  10. 通过添加适当的CSS样式,使得容器显示为竖线,并具有适当的拖拽光标效果。

DragLine`组件的思路是利用事件监听器来捕获鼠标的拖拽行为,计算拖拽宽度,并通过回调函数将更新后的宽度和高度传递给父组件。这样可以实现通过鼠标拖拽来改变容器宽度或者高度的功能。

目录
相关文章
|
6天前
|
前端开发 JavaScript 测试技术
React 分页组件 Pagination
本文介绍了如何在 React 中从零构建分页组件,涵盖基础概念、常见问题及解决方案。通过示例代码详细讲解了分页按钮的创建、分页按钮过多、初始加载慢、状态管理混乱等常见问题的解决方法,以及如何避免边界条件、性能优化和用户反馈等方面的易错点。旨在帮助开发者更好地理解和掌握 React 分页组件的开发技巧,提升应用的性能和用户体验。
26 0
|
25天前
|
移动开发 前端开发 JavaScript
React DnD:实现拖拽功能的终极方案?
本文首发于微信公众号“前端徐徐”,介绍了一个强大的 React 拖拽库——React DnD。React DnD 帮助开发者轻松创建复杂的拖拽界面,适用于 Trello 风格的应用、列表重排序、可拖拽的 UI 组件等场景。文章详细介绍了 React DnD 的基本信息、主要特点、使用场景及快速上手指南。
64 3
React DnD:实现拖拽功能的终极方案?
|
10天前
|
移动开发 前端开发 API
React 拖拽组件 Drag & Drop
本文介绍了在 React 中实现拖拽功能的方法,包括使用原生 HTML5 Drag and Drop API 和第三方库 `react-dnd`。通过代码示例详细讲解了基本的拖拽实现、常见问题及易错点,帮助开发者更好地理解和应用拖拽功能。
36 9
|
5天前
|
前端开发 UED 开发者
React 分页组件 Pagination
本文介绍了如何在 React 中实现分页组件,从基础概念到常见问题及解决方案。分页组件用于将大量数据分成多个页面,提升用户体验。文章详细讲解了分页组件的基本结构、快速入门步骤、以及如何处理页面跳转不平滑、页码过多导致布局混乱、边界条件处理和数据加载延迟等问题。通过本文,读者可以全面了解并掌握 React 分页组件的开发技巧。
10 2
|
9天前
|
设计模式 前端开发 编译器
与普通组件相比,React 泛型组件有哪些优势?
与普通组件相比,React 泛型组件有哪些优势?
25 6
|
17天前
|
前端开发 JavaScript 安全
学习如何为 React 组件编写测试:
学习如何为 React 组件编写测试:
34 2
|
24天前
|
前端开发 JavaScript 测试技术
React 高阶组件 (HOC) 应用
【10月更文挑战第16天】高阶组件(HOC)是 React 中一种复用组件逻辑的方式,通过接受一个组件并返回新组件来实现。本文介绍了 HOC 的基础概念、核心功能和常见问题,包括静态方法丢失、ref 丢失、多个 HOC 组合和 props 冲突的解决方案,并提供了具体的 React 代码示例。通过本文,读者可以更好地理解和应用 HOC,提高代码的复用性和可维护性。
54 8
|
23天前
|
缓存 前端开发 JavaScript
前端serverless探索之组件单独部署时,利用rxjs实现业务状态与vue-react-angular等框架的响应式状态映射
本文深入探讨了如何将RxJS与Vue、React、Angular三大前端框架进行集成,通过抽象出辅助方法`useRx`和`pushPipe`,实现跨框架的状态管理。具体介绍了各框架的响应式机制,展示了如何将RxJS的Observable对象转化为框架的响应式数据,并通过示例代码演示了使用方法。此外,还讨论了全局状态源与WebComponent的部署优化,以及一些实践中的改进点。这些方法不仅简化了异步编程,还提升了代码的可读性和可维护性。
|
11天前
|
前端开发 UED
React 模态框 Modal 组件详解
【10月更文挑战第27天】本文介绍了如何在 React 中实现一个功能完善的模态框组件。从基础概念入手,逐步讲解了简单的模态框实现、CSS 样式、传递子组件、键盘事件处理等高级功能。同时,还探讨了常见问题及易错点,如背景点击关闭、键盘事件冲突和动画效果。通过本文,读者可以全面了解 React 模态框组件的实现细节。
25 0
|
1月前
|
前端开发 JavaScript 调度
React 组件状态(State)
10月更文挑战第8天
23 1