react+ts实现表格的无缝滚动(大屏展示,支持自定义配置,动态列配置等)

表格无缝滚动

动态列表格无缝滚动

  1. 实现效果

    • 无缝滚动
    • 支持自定义传入样式
    • 支持label对象取对象里属性(bind)
    • 支持鼠标移入暂停,移出继续滚动
  2. 实现思路
    通过定时器向上移动。当需要滚动时,定义两个ref,内容一样,第一个滚动完,第二个接上去实现无缝滚动(思路同轮播图)。

  3. 使用示例

    普通表格示例

    效果

    组件使用
    表格列tableData
    对后端返回的tableData简单处理一下,状态的字段加逻辑变个颜色
    处理后的tableData

    动态列使用示例

    效果,日期列是动态列
    效果
    使用
    列
    tableData

  4. 公共组件滚动表格代码实现

/*
 * @Descripttion: 看板滚动表格组件
 * @Author: 小雨滴 <xuyuFighting@163.com>
 * @Date: 2023-09-12 15:07:21
 * @LastEditTime: 2024-05-22 10:40:27
 */
import React, { useRef, useEffect, useState } from 'react';
import style from './scroll.less';

interface Column {
  label: string | object;
  name: string;
  suffix?: string; // 后缀
  color?: string; // 整列颜色
  bind?: string; // label是一个对象时,区对象的哪个属性展示
}

interface ScrollTableProps {
  tableData: any[];
  columnData: Column[];
  lineOverWrap?: boolean; // 行溢出是否换行展示,默认不换行...展示
  tableLineStyle?: {}; // 表格高度,字体大小等样式
  tableHeadStyle?: {}; // 表格头样式
  colorField?: string; // 单元格变色处理,此时要传入对应的color才生效
  color?: string // 单元格颜色
}

export default function ScrollTable(props: ScrollTableProps) {
  const {
    tableData = [],
    columnData = [],
    tableLineStyle = {},
    tableHeadStyle = {},
    lineOverWrap = false,
  } = props;
  const warper = useRef<any>(null);
  const ones = useRef<any>(null);
  const twos = useRef<any>(null);
  const [isScrolle, setIsScrolle] = useState(true);

  useEffect(() => {
    let timer;
    if (isScrolle) {
      if (warper.current.offsetHeight <= ones.current.offsetHeight) {
        twos.current.innerHTML = ones.current.innerHTML;
      }
      timer = setInterval(() => {
        if (warper.current.scrollTop >= ones.current.scrollHeight) {
          warper.current.scrollTop = 0;
        } else {
          warper.current.scrollTop++;
        }
      }, 100);
    }
    return () => {
      clearTimeout(timer);
    };
  }, [isScrolle, tableData.length]);

  const handleMouseOver = () => {
    setIsScrolle(false);
  };

  const handleMouseLeave = () => {
    setIsScrolle(true);
  };

  const getFontColorStyle = (col, item) => {
    const fontStyle = {
      color: 'inherit',
    };
    if (!item.colorField) {
      fontStyle.color = col.color || 'inherit';
    } else if (col.name === item.colorField) {
      fontStyle.color = item.color || 'inherit';
    }

    return fontStyle;
  };

  return (
    <div
      className={style['my-content-center']}
      onMouseOver={handleMouseOver}
      onMouseLeave={handleMouseLeave}
      onFocus={() => {}}
    >
      <div className={style['my-content-center-table-header']} style={tableHeadStyle}>
        {columnData.map((item: any) => {
          return (
            <div
              key={item.name}
              className={`${style['column-head']} ${style['column-week']}`}
              title={item.label}
            >
              <div>{item.label}</div>
            </div>
          );
        })}
      </div>
      <div ref={warper} className={style['my-content-center-content']}>
        <div ref={ones} className={style['my-content-center-table-content']}>
          {tableData.length
            ? tableData.map((item: any, index: number) => {
                return (
                  <div
                    className={
                      lineOverWrap
                        ? style['my-content-center-table-content-wrap']
                        : style['my-content-center-table-content-item']
                    }
                    key={String(index)}
                    style={tableLineStyle}
                  >
                    {columnData.map((val: Column, i: number) => {
                      return (
                        <div
                          key={String(i)}
                          // className={style['my-content-center-table-content-item-item']}
                          className={
                            lineOverWrap
                              ? style['my-content-center-table-content-wrap-item']
                              : style['my-content-center-table-content-item-item']
                          }
                          style={getFontColorStyle(val, item)}
                          title={`${val.bind ? item[val.name][val.bind] : item[val.name]} ${
                            val.suffix || ''
                          }`}
                        >
                          {val.bind ? item[val.name][val.bind] : item[val.name]}
                          {val.suffix || ''}
                        </div>
                      );
                    })}
                  </div>
                );
              })
            : null}
        </div>
        {tableData.length ? (
          <div ref={twos} className={style['my-content-center-table-content']} />
        ) : null}
      </div>
    </div>
  );
}

less代码如下

/*
 * @Descripttion: 看板滚动表格组件
 * @Author: 小雨滴 <xuyuFighting@163.com>
 * @Date: 2023-09-12 15:07:21
 * @LastEditTime: 2024-05-22 10:40:27
 */
.my-content-center {
  width: 100%;
  height: 100%;
  margin-bottom: 30px;
  color: #fff;
  font-size: 16px;

  &-table-header {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    justify-content: space-between;
    width: 100%;
    height: 50px;
    line-height: 50px;
    background: rgba(130, 254, 255, 0.25);

    .column-head {
      flex: 1;
      overflow: hidden;
      color: #00ffd8;
      white-space: nowrap;
      text-align: center;
      text-overflow: ellipsis;
    }
  }

  &-content {
    height: calc(100% - 50px);
    overflow: hidden;
  }

  &-table-content {
    width: 100%;
    overflow: auto;
    &-item {
      display: flex;
      flex-direction: row;
      flex-wrap: wrap;
      justify-content: space-between;
      width: 100%;
      height: 50px;
      overflow: hidden;
      line-height: 50px;
      &:nth-of-type(even) {
        // background: #0E2B2F;
        background: rgba(130, 254, 255, 0.08);
      }

      &-item {
        flex: 1;
        height: 100%;
        overflow: hidden;
        white-space: nowrap;
        text-align: center;
        text-overflow: ellipsis;
      }
    }

    &-wrap {
      display: flex;
      flex-direction: row;
      flex-wrap: wrap;
      align-items: center;
      justify-content: space-between;
      width: 100%;
      min-height: 50px;
      overflow: hidden;
      &:nth-of-type(even) {
        // background: #0E2B2F;
        background: rgba(130, 254, 255, 0.08);
      }

      &-item {
        flex: 1;
        height: 100%;
        text-align: center;
      }
    }
  }
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
React TS是一个用于构建用户界面的JavaScript库,而VR看房可以通过使用WebVR技术来实现。在React TS实现VR看房需要以下步骤: 1. 了解WebVR技术:WebVR是一种使Web应用程序能够在虚拟现实设备上运行的技术,它提供了一种在虚拟现实设备上渲染内容的方式。 2. 导入WebVR库:在React TS项目中,需要导入与WebVR相关的库,例如A-Frame或React 360等,这些库提供了一些用于构建VR界面的组件和功能。 3. 创建VR场景:使用React TS组件化开发方式,可以通过在项目中创建VR场景组件来构建VR看房的界面。可以使用库中提供的组件来构建3D场景、添加虚拟现实设备的交互等。 4. 加载房屋模型:在VR场景中加载房屋模型,可以使用库中提供的加载器将3D房屋模型导入到场景中,并设置适当的位置和缩放。 5. 添加交互功能:为了实现VR看房的功能,需要添加一些交互功能,例如移动、旋转和缩放房屋模型,点击房间以获取更多信息等。可以使用库中提供的交互组件自定义事件处理程序来实现这些功能。 6. 兼容不同的设备:考虑到不同的虚拟现实设备,需要在React TS项目中进行一些适配工作,以确保VR看房界面在不同设备上的兼容性。 总的来说,使用React TS实现VR看房需要对WebVR技术有一定的了解,并结合具体的库和组件来构建VR场景、加载房屋模型,并添加交互功能。不同设备的兼容性也是一个需要考虑的因素。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值