찾다
웹 프론트엔드프런트엔드 Q&A반응에서 구성 요소 크기를 변경하는 방법

React에서 구성 요소의 크기를 변경하는 방법: 1. "React.cloneElement"를 사용하여 래핑된 구성 요소를 향상합니다. 2. 래핑된 구성 요소에 절대 위치를 설정하고 구성 요소 내에 크기 조정 가능한 드래그 바 4개를 추가합니다. 바와 드래그는 DragBox의 크기를 변경합니다.

반응에서 구성 요소 크기를 변경하는 방법

이 튜토리얼의 운영 환경: Windows 10 시스템, React18 버전, Dell G3 컴퓨터.

반응에서 구성 요소 크기를 변경하는 방법은 무엇입니까?

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>

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
usestate () vs. usereducer () : 주 요구에 맞는 올바른 후크 선택usestate () vs. usereducer () : 주 요구에 맞는 올바른 후크 선택Apr 24, 2025 pm 05:13 PM

chelectionSimple, IndependentStateVaribles; useUserEducer () useuserEducer () forcomplexStateLogicor () whenStatedSonpreviousState.1) usestate () isidealforsimpleupdatesliketogglingabooleorupdatingacounter.2) usbetterformanagingmentiplesub-vvalusorac

usestate ()로 상태 관리 : 실용적인 자습서usestate ()로 상태 관리 : 실용적인 자습서Apr 24, 2025 pm 05:05 PM

Usestate는 클래스 구성 요소 및 기타 상태 관리 솔루션보다 우수합니다. 국가 관리를 단순화하고 코드를 더 명확하게하고 읽기 쉽고 React의 선언적 특성과 일치하기 때문입니다. 1) Usestate는 함수 구성 요소에서 상태 변수를 직접 선포 할 수있게합니다. 2) 후크 메커니즘을 통해 다시 렌더링하는 동안 상태를 기억합니다.

usestate ()를 사용하고 대체 상태 관리 솔루션을 고려할 때usestate ()를 사용하고 대체 상태 관리 솔루션을 고려할 때Apr 24, 2025 pm 04:49 PM

useUsestate () forlocalcomponentStateManagement; 고려 사항 forglobalstate, complexlogic, orperformanceissues.1) usestate () isidealforsimple, localstate.2) useglobalstatesolutionslikereduxorcontextforsharedstate.3) optforredooxtoolkitormobxcomcoccomcoccomcoccomcoccomcoccomcoccomcoccomcoccomporccomcoccomporccomcoccomport

React의 재사용 가능한 구성 요소 : 코드 유지 관리 및 효율성 향상React의 재사용 가능한 구성 요소 : 코드 유지 관리 및 효율성 향상Apr 24, 2025 pm 04:45 PM

reusablecomponentsinreacececodemainabenabilityandefficiency는 hallowingesamecomponentacrossdifferentpartsofanapplicationorprojects.1) 그들을 retuduceredundancyandsimplifyupdates.2) theyseconsistencyinuserexperience.3) theyquireoptim

React의 가상 DOM : 효율적인 업데이트를 통한 성능 향상React의 가상 DOM : 효율적인 업데이트를 통한 성능 향상Apr 24, 2025 pm 04:41 PM

thevirtualdomisAlightIgentin-memorycopyofTherealDoModedByReaCtTooptimizeUiUpdates.itboostSperformanceByminiMizingDirectDomManipulationThevirtOdMomfirst, thenecessAppledOnyCesseAcTeActualDom.

HTML 및 React의 통합 : 실용 가이드HTML 및 React의 통합 : 실용 가이드Apr 21, 2025 am 12:16 AM

HTML 및 React는 JSX를 통해 완벽하게 통합하여 효율적인 사용자 인터페이스를 구축 할 수 있습니다. 1) JSX를 사용하여 HTML 요소를 포함시킵니다. 2) Virtual DOM을 사용하여 렌더링 성능을 최적화, 3) 구성 요소화를 통해 HTML 구조를 관리하고 렌더링합니다. 이 통합 방법은 직관적 일뿐 만 아니라 응용 프로그램 성능을 향상시킵니다.

React 및 HTML : 데이터 렌더링 및 처리 이벤트React 및 HTML : 데이터 렌더링 및 처리 이벤트Apr 20, 2025 am 12:21 AM

상태 및 소품을 통해 데이터를 효율적으로 렌더링하고 합성 이벤트 시스템을 통해 사용자 이벤트를 처리합니다. 1) usestate를 사용하여 카운터 예제와 같은 상태를 관리하십시오. 2) 버튼 클릭과 같은 JSX에 함수를 추가하여 이벤트 처리가 구현됩니다. 3) Todolist 구성 요소와 같은 목록을 렌더링하려면 주요 속성이 필요합니다. 4) 양식 처리의 경우 양식 구성 요소와 같은 usestate 및 e.preventDefault ().

백엔드 연결 : 반응이 서버와 상호 작용하는 방법백엔드 연결 : 반응이 서버와 상호 작용하는 방법Apr 20, 2025 am 12:19 AM

반응은 HTTP 요청을 통해 서버와 상호 작용하여 데이터를 획득, 전송, 업데이트 및 삭제합니다. 1) 사용자 작동 이벤트 트리거, 2) HTTP 요청 시작, 3) 프로세스 서버 응답, 4) 구성 요소 상태 및 재 렌더 업데이트.

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 옷 제거제

Video Face Swap

Video Face Swap

완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

뜨거운 도구

에디트플러스 중국어 크랙 버전

에디트플러스 중국어 크랙 버전

작은 크기, 구문 강조, 코드 프롬프트 기능을 지원하지 않음

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

Dreamweaver Mac版

Dreamweaver Mac版

시각적 웹 개발 도구

MinGW - Windows용 미니멀리스트 GNU

MinGW - Windows용 미니멀리스트 GNU

이 프로젝트는 osdn.net/projects/mingw로 마이그레이션되는 중입니다. 계속해서 그곳에서 우리를 팔로우할 수 있습니다. MinGW: GCC(GNU Compiler Collection)의 기본 Windows 포트로, 기본 Windows 애플리케이션을 구축하기 위한 무료 배포 가능 가져오기 라이브러리 및 헤더 파일로 C99 기능을 지원하는 MSVC 런타임에 대한 확장이 포함되어 있습니다. 모든 MinGW 소프트웨어는 64비트 Windows 플랫폼에서 실행될 수 있습니다.