検索
ホームページウェブフロントエンドフロントエンドQ&AReactでコンポーネントのサイズを変更する方法
Reactでコンポーネントのサイズを変更する方法Dec 21, 2022 pm 04:04 PM
reactコンポーネント

React でコンポーネントのサイズを変更する方法: 1. 「React.cloneElement」を使用してラップされたコンポーネントを強化します; 2. ラップされたコンポーネントに絶対位置を設定し、コンポーネント内にサイズ変更可能な 4 つのドラッグ バーを追加します。 ;3. ドラッグ バーをクリックしてドラッグし、DragBox のサイズを変更します。

Reactでコンポーネントのサイズを変更する方法

#このチュートリアルの動作環境: Windows 10 システム、react18 バージョン、Dell G3 コンピューター。

React でコンポーネントのサイズを変更するにはどうすればよいですか?

React のドラッグ アンド ドロップ サイズ変更コンポーネントの手書き

1. 実装プロセス

1. React.cloneElement を使用してパッケージ コンポーネントを強化し、パッケージ コンポーネントの絶対値 コンポーネント内にサイズ変更可能な 4 つのドラッグ バーを配置して追加します。ドラッグ バーをクリックしてドラッグすると、DragBox のサイズが次のように変わります。

2. 使用方法:

<DragBox dragAble={true} minWidth={350} minHeight={184} edgeDistance={[10, 10, 10, 10]} dragCallback={this.dragCallback} >
{/* 使用DragBox拖动组件包裹需要调整大小的盒子 */}
   <div style={{ top: 100 + &#39;px&#39;, left: 100 + &#39;px&#39;, width: 350, height: 184, backgroundColor: "white" }}>
        <div style={{ backgroundColor: "yellow", width: "100%", height: 30 }}></div>
        <div style={{ backgroundColor: "green", width: "100%", height: 30 }}></div>
        <div style={{ backgroundColor: "blue", width: "100%", height: 30 }}></div>
    </div>
</DragBox>
Reactでコンポーネントのサイズを変更する方法 2. コード

DragBox コンポーネント

import React, { Component, Fragment } from &#39;react&#39;;
import styles from "./DragBox.less";
/**
 * 拖拽的公共组件
 * 接收参数:
 *      dragAble:是否开启拖拽
 *      minWidth:最小调整宽度
 *      minHeight:最小调整高度
 *      edgeDistance:数组,拖拽盒子里浏览器上下左右边缘的距离,如果小于这个距离就不会再进行调整宽高
 *      dragCallback:拖拽回调
 * 
 * 使用:
 *      在DragBox组件放需要实现拖拽的div,DragBox组件内会设置position:absolute(React.cloneElement)
 */
class DragBox extends Component {
    constructor(props) {
        super(props);
        // 父组件盒子
        this.containerRef = React.createRef();
        // 是否开启尺寸修改
        this.reSizeAble = false;
        // 鼠标按下时的坐标,并在修改尺寸时保存上一个鼠标的位置
        this.clientX, this.clientY;
        // 鼠标按下时的位置,使用n、s、w、e表示
        this.direction = "";
        // 拖拽盒子里浏览器上下左右边缘的距离,如果小于这个距离就不会再进行调整宽高
        this.edgeTopDistance = props.edgeDistance[0] || 10;
        this.edgeBottomDistance = props.edgeDistance[1] || 10;
        this.edgeLeftDistance = props.edgeDistance[2] || 10;
        this.edgeRightDistance = props.edgeDistance[3] || 10;
    }
    componentDidMount(){
        // body监听移动事件
        document.body.addEventListener(&#39;mousemove&#39;, this.move);
        // 鼠标松开事件
        document.body.addEventListener(&#39;mouseup&#39;, this.up);
    }
    /**
     * 清除调整宽高的监听
     */
    clearEventListener() {
        document.body.removeEventListener(&#39;mousemove&#39;, this.move);
        document.body.removeEventListener(&#39;mouseup&#39;, this.up);
    }
    componentWillUnmount() {
        this.clearEventListener();
    }
    /**
     * 鼠标松开时结束尺寸修改
     */
    up = () => {
        this.reSizeAble = false;
        this.direction = "";
    }
    /**
     * 鼠标按下时开启尺寸修改
     * @param {*} e 
     * @param {String} direction 记录点击上下左右哪个盒子的标识
     */
    down = (e, direction) => {
        this.direction = direction;
        this.reSizeAble = true;
        this.clientX = e.clientX;
        this.clientY = e.clientY;
    }
    /**
     * 鼠标按下事件 监听鼠标移动,修改父节dom位置
     * @param {DocumentEvent} e 事件参数
     * @param {Boolean} changeLeft 是否需要调整left
     * @param {Boolean} changeTop 是否需要调整top
     * @param {Number} delta 调整位置的距离差
     */
    changeLeftAndTop = (event, changeLeft, changeTop, delta) => {
        let ww = document.documentElement.clientWidth;
        let wh = window.innerHeight;
        if (event.clientY < 0 || event.clientX < 0 || event.clientY > wh || event.clientX > ww) {
            return false;
        }
        if (changeLeft) { 
            this.containerRef.current.style.left = Math.max(this.containerRef.current.offsetLeft + delta, this.edgeLeftDistance) + &#39;px&#39;; 
        }
        if (changeTop) { 
            this.containerRef.current.style.top = Math.max(this.containerRef.current.offsetTop + delta, this.edgeTopDistance) + &#39;px&#39;; 
        }
    }
    /**
     * 鼠标移动事件
     * @param {*} e 
     */
    move = (e) => {
        // 当开启尺寸修改时,鼠标移动会修改div尺寸
        if (this.reSizeAble) {
            let finalValue;
            // 鼠标按下的位置在上部,修改高度
            if (this.direction === "top") {
                // 1.距离上边缘10 不修改
                // 2.因为按着顶部修改高度会修改top、height,所以需要判断e.clientY是否在offsetTop和this.clientY之间(此时说明处于往上移动且鼠标位置在盒子上边缘之下),不应该移动和调整盒子宽高
                if (e.clientY <= this.edgeTopDistance || (this.containerRef.current.offsetTop < e.clientY && e.clientY  < this.clientY)){ 
                    this.clientY = e.clientY;
                    return; 
                }
                finalValue = Math.max(this.props.minHeight, this.containerRef.current.offsetHeight + (this.clientY - e.clientY));
                // 移动的距离,如果移动的距离不为0需要调整高度和top
                let delta = this.containerRef.current.offsetHeight - finalValue;
                if(delta !== 0){
                    this.changeLeftAndTop(e, false, true, delta); 
                    this.containerRef.current.style.height = finalValue + "px";
                }
                this.clientY = e.clientY;
            } else if (this.direction === "bottom") {// 鼠标按下的位置在底部,修改高度
                // 1.距离下边缘10 不修改
                // 2.判断e.clientY是否处于往下移动且鼠标位置在盒子下边缘之上,不应该调整盒子宽高
                if (window.innerHeight - e.clientY <= this.edgeBottomDistance || (this.containerRef.current.offsetTop + this.containerRef.current.offsetHeight > e.clientY && e.clientY  > this.clientY)) { 
                    this.clientY = e.clientY;
                    return; 
                }
                finalValue = Math.max(this.props.minHeight, this.containerRef.current.offsetHeight + (e.clientY - this.clientY));
                this.containerRef.current.style.height = finalValue + "px";
                this.clientY = e.clientY;
            } else if (this.direction === "right") { // 鼠标按下的位置在右边,修改宽度 
                // 1.距离右边缘10 不修改
                // 2.判断e.clientY是否处于往右移动且鼠标位置在盒子右边缘之左,不应该调整盒子宽高
                if (document.documentElement.clientWidth - e.clientX <= this.edgeRightDistance || (this.containerRef.current.offsetLeft + this.containerRef.current.offsetWidth > e.clientX && e.clientX  > this.clientX)) { 
                    this.clientX = e.clientX;
                    return;
                }
                // 最小为UI设计this.props.minWidth,最大为 改边距离屏幕边缘-10,其他同此
                let value = this.containerRef.current.offsetWidth + (e.clientX - this.clientX);
                finalValue = step(value, this.props.minWidth, document.body.clientWidth - this.edgeRightDistance - this.containerRef.current.offsetLeft);
                this.containerRef.current.style.width = finalValue + "px";
                this.clientX = e.clientX;
            } else if (this.direction === "left") {// 鼠标按下的位置在左边,修改宽度
                // 1.距离左边缘10 不修改
                // 2.因为按着顶部修改高度会修改left、height,所以需要判断e.clientY是否在offsetLeft和this.clientY之间(此时说明处于往左移动且鼠标位置在盒子左边缘之左),不应该移动和调整盒子宽高
                if (e.clientX <= this.edgeLeftDistance || (this.containerRef.current.offsetLeft < e.clientX && e.clientX  < this.clientX)) { 
                    this.clientX = e.clientX;
                    return; 
                }
                let value = this.containerRef.current.offsetWidth + (this.clientX - e.clientX);
                finalValue = step(value, this.props.minWidth, this.containerRef.current.offsetWidth - this.edgeLeftDistance + this.containerRef.current.offsetLeft);
                // 移动的距离,如果移动的距离不为0需要调整宽度和left
                let delta = this.containerRef.current.offsetWidth - finalValue;
                if(delta !== 0){
                    // 需要修改位置,直接修改宽度只会向右增加
                    this.changeLeftAndTop(e, true, false, delta); 
                    this.containerRef.current.style.width = finalValue + "px";
                }
                this.clientX = e.clientX;
            }
            this.props.dragCallback && this.props.dragCallback(this.direction, finalValue);
        }
    }
    render() {
        // 四个红色盒子 用于鼠标移动到上面按下进行拖动
        const children = (
            <Fragment key={"alphaBar"}>
                <div key={1} className={styles.alphaTopBar} onMouseDown={(e) => this.down(e, "top")}></div>
                <div key={2} className={styles.alphaBottomBar} onMouseDown={(e) => this.down(e, "bottom")}></div>
                <div key={3} className={styles.alphaLeftBar} onMouseDown={(e) => this.down(e, "left")}></div>
                <div key={4} className={styles.alphaRightBar} onMouseDown={(e) => this.down(e, "right")}></div>
            </Fragment>
        );
        // 给传进来的children进行加强:添加position:"absolute",添加四个用于拖动的透明盒子
        const childrenProps = this.props.children.props;
        const cloneReactElement = React.cloneElement(
            this.props.children,
            {
                style: {
                    // 复用原来的样式
                    ...childrenProps.style,
                    // 添加position:"absolute"
                    position: "absolute"
                },
                ref: this.containerRef
            },
            // 复用children,添加四个用于拖动的红色盒子
            [childrenProps.children, children]
        );
        return (
            <Fragment>
                {
                    cloneReactElement
                }
            </Fragment>
        );
    }
}
/**
 * 取最大和最小值之间的值
 * @param {*} value 
 * @param {*} min 
 * @param {*} max 
 * @returns 
 */
function step(value, min, max) {
    if (value < min) {
        return min;
    } else if (value > max) {
        return max;
    } else {
        return value;
    }
}
export default DragBox;

DragBox コンポーネントのドラッグ バー スタイル

  .alphaTopBar{
    position: absolute;
    width: 100%;
    height: 8px;
    top: -5px;
    left: 0;
    background-color: red;
    cursor: row-resize;
  }
  .alphaBottomBar{
    position: absolute;
    width: 100%;
    height: 8px;
    bottom: -5px;
    left: 0;
    background-color: red;
    cursor: row-resize;
  }
  .alphaLeftBar{
    position: absolute;
    width: 8px;
    height: 100%;
    top: 0;
    left: -5px;
    background-color: red;
    cursor: col-resize;
  }
  .alphaRightBar{
    position: absolute;
    width: 8px;
    height: 100%;
    top: 0;
    right: -5px;
    background-color: red;
    cursor: col-resize;
  }

推奨学習: "

反応ビデオチュートリアル

>>

以上がReactでコンポーネントのサイズを変更する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
VUE3开发基础:使用extends继承组件VUE3开发基础:使用extends继承组件Jun 16, 2023 am 08:58 AM

Vue是目前最流行的前端框架之一,而VUE3则是Vue框架的最新版本,相较于VUE2,VUE3具备了更高的性能和更出色的开发体验,成为了众多开发者的首选。在VUE3中,使用extends继承组件是一个非常实用的开发方式,本文将为大家介绍如何使用extends继承组件。extends是什么?在Vue中,extends是一个非常实用的属性,它可以用于子组件继承父

如何使用 Vue 实现日历组件?如何使用 Vue 实现日历组件?Jun 25, 2023 pm 01:28 PM

Vue是一款非常流行的前端框架,它提供了很多工具和功能,如组件化、数据绑定、事件处理等,能够帮助开发者构建出高效、灵活和易维护的Web应用程序。在这篇文章中,我来介绍如何使用Vue实现一个日历组件。1、需求分析首先,我们需要分析一下这个日历组件的需求。一个基本的日历应该具备以下功能:展示当前月份的日历页面;支持切换到前一月或下一月;支持点击某一天,

聊聊Vue怎么通过JSX动态渲染组件聊聊Vue怎么通过JSX动态渲染组件Dec 05, 2022 pm 06:52 PM

Vue怎么通过JSX动态渲染组件?下面本篇文章给大家介绍一下Vue高效通过JSX动态渲染组件的方法,希望对大家有所帮助!

VSCode插件分享:一个实时预览Vue/React组件的插件VSCode插件分享:一个实时预览Vue/React组件的插件Mar 17, 2022 pm 08:07 PM

在VSCode中开发Vue/React组件时,怎么实时预览组件?本篇文章就给大家分享一个VSCode 中实时预览Vue/React组件的插件,希望对大家有所帮助!

VUE3开发入门教程:使用组件实现分页VUE3开发入门教程:使用组件实现分页Jun 16, 2023 am 08:48 AM

VUE3开发入门教程:使用组件实现分页分页是一个常见的需求,因为在实际开发中,我们往往需要将大量的数据分成若干页以展示给用户。在VUE3开发中,可以通过使用组件实现分页功能,本文将介绍如何使用组件实现简单的分页功能。1.创建组件首先,我们需要创建一个分页组件,使用“vuecreate”命令创建VUE项目,并在src/components目录下创建Pagin

如何使用 Vue 实现仿照片墙组件?如何使用 Vue 实现仿照片墙组件?Jun 25, 2023 am 08:19 AM

在现代Web开发中,组件化是一个极受欢迎的开发模式。而Vue.js则是一个非常适合组件化的前端框架。在这篇文章中,我们将介绍如何使用Vue.js创建一个仿照片墙组件。在开始之前,我们需要明确一些准备工作。首先,我们需要安装Vue.js。安装的方法非常简单,只需在终端中输入以下命令:npminstallvue安装完成后,我们可以创建一个名为

常用 Vue UI 组件的使用技巧常用 Vue UI 组件的使用技巧Jun 25, 2023 am 08:31 AM

在现代Web开发中,UI组件是不可或缺的一部分。Vue.js框架中有许多优秀的UI组件库,如Element-UI、Vuetify、AntDesignVue等。这些组件库提供了许多易于使用的组件,可以帮助我们更加高效地创建Web应用程序。本文将介绍一些常用的VueUI组件,以及使用这些组件的技巧和实用技能。一、El-TableEl-Table是Eleme

VUE3初学者入门:使用Vue.js组件组合实现可复用组合VUE3初学者入门:使用Vue.js组件组合实现可复用组合Jun 15, 2023 pm 08:53 PM

Vue.js是一款流行的前端JavaScript框架,它提供了一种简单易用的方式来构建动态网页应用程序。Vue.js的主要特点是其模块化的设计和可插拔的组件系统。这使得开发者可以轻松地创建可复用的组件,从而提高了应用程序的重用性和可维护性。在本文中,我们将重点介绍VUE3初学者如何使用Vue.js组件组合实现可复用组合。Vue.js组件是一个完整的封装元素,

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

DVWA

DVWA

Damn Vulnerable Web App (DVWA) は、非常に脆弱な PHP/MySQL Web アプリケーションです。その主な目的は、セキュリティ専門家が法的環境でスキルとツールをテストするのに役立ち、Web 開発者が Web アプリケーションを保護するプロセスをより深く理解できるようにし、教師/生徒が教室環境で Web アプリケーションを教え/学習できるようにすることです。安全。 DVWA の目標は、シンプルでわかりやすいインターフェイスを通じて、さまざまな難易度で最も一般的な Web 脆弱性のいくつかを実践することです。このソフトウェアは、

PhpStorm Mac バージョン

PhpStorm Mac バージョン

最新(2018.2.1)のプロフェッショナル向けPHP統合開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

このプロジェクトは osdn.net/projects/mingw に移行中です。引き続きそこでフォローしていただけます。 MinGW: GNU Compiler Collection (GCC) のネイティブ Windows ポートであり、ネイティブ Windows アプリケーションを構築するための自由に配布可能なインポート ライブラリとヘッダー ファイルであり、C99 機能をサポートする MSVC ランタイムの拡張機能が含まれています。すべての MinGW ソフトウェアは 64 ビット Windows プラットフォームで実行できます。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境