React+Ts左右二级联动

美团中的左右二级联动简单效果实现: 

import React, { Component, createRef } from 'react'
import "./index.less";
export default class index extends Component {
    // 声明控制下标的状态 和开关的状态
    state = { Index: 0, flag: true }
    // 渲染数据
    arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18];
    // 保存右部子盒子每次递增的高度 用于计算scroll
    array: number[] = []
    // 保存子盒子的高度
    hi: number = 0
    // 保存右部子盒子每次递增的高度
    height: number = 0
    // 左部大盒子
    left = createRef<HTMLDivElement>();
    // 右部大盒子
    right = createRef<HTMLDivElement>();
    // 利用方法对左部大盒子元素进行返回值 方便我们调用该元素
    getleft = () => (this.left.current as HTMLDivElement)
    // 利用方法对右部大盒子元素进行返回 方便我们调用该元素
    getright = () => (this.right.current as HTMLDivElement)
    // React生命周期 在组件挂载完毕后执行
    componentDidMount() {
        // 保存右部子级盒子的高度
        this.hi = (this.getright().children[0] as HTMLDivElement).offsetHeight
        // 默认往我们的数组中添加一个0;解决我们点击第一个元素时会滑动的问题
        this.array.push(this.height);
        // 对右部的所有子级盒子进行遍历  
        this.getright().childNodes.forEach(item => {
            // 对每次的子级盒子的高度进行递增, 1+2  2+3  3+4  4+5  数字为下标元素
            this.height += (item as HTMLDivElement).offsetHeight
            // 将每次递增后的数值添加进我们提前声明好的数值数组中
            this.array.push(this.height);
        })
    }
    start(index: number) {
        // 通过Reactapi this.setState 对小标进行更新,并关闭开关 用于阻止scroll事件后续的代码执行
        this.setState({ Index: index, flag: false });
        // 用当前点击元素的下标 称与 右部自己盒子的高度 来计算出右部大盒子scrollTop滚动多少距离
        this.getright().scrollTop = this.hi * index
        // 三元运算 让左部发生运动 让选中元素保持在中间位置
        this.getleft().scrollTop = index >= 4 ? (index - 3) * 100 : 0
    }
    scroll = () => {
        // 判断当前状态里的开关是否打开 没有打开 直接return 阻止后续的事件逻辑执行
        if (this.state.flag === false) return
        // 对我们保存递增高度的数组进行遍历判断
        this.array.forEach((item, index) => {
            // 判断右部盒子scrollTop滚动距离是否大于  我们所保存的每一个递增的高度值 大于就将其对应下标进行状态更新
            if (this.getright().scrollTop >= item - 80) {
                this.setState({ Index: index });
                // 三元运算 让左部盒子发生运动 让选中元素保持在中间位置
                this.getleft().scrollTop = index >= 4 ? (index - 3) * 100 : 0;
            }
        });
    }
    // 触摸事件  当我们触摸之后打开开关灯 让scroll事件的后续代码可以执行
    Fnend = () => { this.setState({ flag: true }) }
    render() {
        // 结构赋值  可以快速的保存设置状态里的值
        var { Index } = this.state
        return (
            <div className='LeftRight-LingAge'>
                <div className="Lingage-left" ref={this.left}>
                    {this.arr.map((item, index) => <div style={{ background: Index === index ? '#09c' : '' }} onTouchStart={this.start.bind(this, index)} key={item}>
                        {item}
                    </div>)}
                </div>
                <div className="Lingage-right" ref={this.right} onScroll={this.scroll} onTouchStart={this.Fnend.bind(this)}>
                    {this.arr.map((item, index) => <div key={item}>
                        {item}
                    </div>)}
                </div>
            </div>
        )
    }
}
  • index.less
.LeftRight-LingAge {
    width: 100vw;
    height: 100vh;
    background: skyblue;
    display: flex;
    overflow: hidden;

    .Lingage-left::-webkit-scrollbar {
        display: none;
    }

    .Lingage-right::-webkit-scrollbar {
        display: none;
    }

    .Lingage-left {
        overflow-y: scroll;
        scroll-behavior: smooth;
        width: 120px;
        height: 100%;
        background-color: pink;

        div {
            width: 100%;
            height: 100px;
            font-size: 18px;
            text-align: center;
            line-height: 100px;
            font-size: 30px;
        }
    }

    .Lingage-right {
        overflow-y: scroll;
        scroll-behavior: smooth;
        width: 280px;
        height: 100vh;

        >div {
            text-align: center;
            font-size: 40px;
            width: 100%;
            height: 110%;
            background-color: goldenrod;
        }

        >div:nth-child(2n) {
            background-color: #999;
        }
    }
}

如有高见可在评论区发言

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React+TypeScript脚手架是一种用于创建React项目的工具。通过使用create-react-app脚手架,可以快速搭建一个React项目,并且使用TypeScript作为项目的开发语言。\[1\] 使用步骤如下: 1. 首先,需要安装create-react-app工具。可以通过以下命令进行安装: ``` npm i create-react-app -g ``` 或者 ``` yarn add create-react-app -g ``` 2. 然后,使用create-react-app命令来创建一个React+TypeScript项目。命令的格式如下: ``` npx create-react-app <项目名> --template typescript ``` 注意,项目名不要使用中文,否则会报错。\[2\] 3. 创建完成后,可以在VSCode中打开项目。可以看到项目中已经生成了React项目的雏形,组件的后缀为.tsx,这说明成功创建了React+TypeScript项目。\[1\] 4. 在项目中,可以根据需要进行配置。通常,可以在App组件中进行配置,例如引入所需的组件、样式和路由等。\[3\] 希望以上信息对你有帮助!如果还有其他问题,请随时提问。 #### 引用[.reference_title] - *1* *3* [react+ts搭建](https://blog.csdn.net/m0_56540662/article/details/124267829)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [React+ts搭建脚手架](https://blog.csdn.net/weixin_51612593/article/details/120249135)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值