亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

基于React實(shí)現(xiàn)無限滾動(dòng)表格

 更新時(shí)間:2023年11月10日 08:36:14   作者:寄給江南  
以文本為例,為了實(shí)現(xiàn)無限循環(huán)的視覺效果,我們需要準(zhǔn)備兩段相同的文本,并讓第二段文本的頭部銜接在第一段文本的尾部,同時(shí),為兩段文本設(shè)置相同的滾動(dòng)動(dòng)畫,本文給大家介紹了基于React實(shí)現(xiàn)無限滾動(dòng)表格,需要的朋友可以參考下

無限滾動(dòng)效果

以文本為例,為了實(shí)現(xiàn)無限循環(huán)的視覺效果,我們需要準(zhǔn)備兩段相同的文本,并讓第二段文本的頭部銜接在第一段文本的尾部。同時(shí),為兩段文本設(shè)置相同的滾動(dòng)動(dòng)畫。

當(dāng)?shù)谝欢挝谋緷L動(dòng)到尾部時(shí),如果能讓第一段文本的位置瞬間移動(dòng)回頭部,并將第一段文本的頭部?jī)?nèi)容替換為第二段的頭部?jī)?nèi)容,同時(shí)動(dòng)畫也回到開始位置,這樣,用戶從視覺效果上看是感受不到變化的。

以下代碼是 Marquee 組件及其樣式的簡(jiǎn)單實(shí)現(xiàn)。

// Marquee.tsx
export default function Marquee(props) {
  const { children } = props;
  return (
    <div className={styles.marquee}>
      <div className={styles.ctx}>{children}</div>
      <div className={styles.ctx}>{children}</div>
    </div>
  );
}

// App.tsx
export default function App() {
  return (
    <Marquee>只期待 後來的你 能快樂 那就是 後來的我 最想的</Marquee>
  );
}
// Marquee.module.scss
.marquee {
  width: 40px;
  overflow: hidden;
  position: relative;

  .ctx {
    animation: scroll 4s infinite linear; // 指定滾動(dòng)動(dòng)畫
  }
}

@keyframes scroll {
  0% {
    transform: translateY(0);
  }
  100% {
    transform: translateY(-100%);
  }
}

懸停效果

實(shí)現(xiàn)鼠標(biāo)懸停效果,通常有兩種方法:

  • 聲明 isHovered 變量,通過 onMouseEnteronMouseLeave 事件改變 isHovered 的值,從而實(shí)現(xiàn)懸停效果。
  • 使用 :hover 偽類,通過設(shè)置 animation-play-state 屬性控制動(dòng)畫的運(yùn)行,從而實(shí)現(xiàn)懸停效果。

本文使用第二種方法,為整個(gè)外層容器設(shè)置 :hover 樣式。當(dāng)鼠標(biāo)懸浮在整個(gè)容器上時(shí),讓內(nèi)部元素的動(dòng)畫暫停。我們?cè)?Marquee.module.scss 文件中添加如下樣式:

// ...
.marquee:hover {
  .ctx {
    animation-play-state: paused;
  }
}

到此,最基本的功能已經(jīng)實(shí)現(xiàn),接下來開始實(shí)現(xiàn)表格組件的無限滾動(dòng)。

表格的無限滾動(dòng)

首先,實(shí)現(xiàn)根據(jù)配置動(dòng)態(tài)生成表格的功能。我們從傳入的對(duì)象數(shù)組中提取所有的鍵,作為表頭內(nèi)容。

本文實(shí)現(xiàn)的表頭提取函數(shù)考慮了傳入可選參數(shù)的情況,因此它會(huì)遍歷所有列表項(xiàng)并提取所有存在的鍵。如果表頭屬性是固定數(shù)量的話,可以使用更簡(jiǎn)便的方法來提取鍵。

提取出表頭后,我們就可以遍歷對(duì)象數(shù)組中的每一項(xiàng),并根據(jù)對(duì)應(yīng)的鍵將屬性值填入相應(yīng)的單元格中,逐步構(gòu)建起表格內(nèi)容。

基于上述步驟分析,表格組件的初步實(shí)現(xiàn)如下(樣式在文章末尾給出):

// DataTable.tsx
export default function DataTable<T extends object>({ dataSource }: { dataSource: Array<T> }) {
  if (!Array.isArray(dataSource) || dataSource.length === 0) {
    return null; // 數(shù)據(jù)源不是數(shù)組或數(shù)組為空,停止操作
  }

  const labelList = dataSource.reduce((acc: any, cur: any) => {
    const keys = Object.keys(cur);
    for (const key of keys) {
      if (!acc.includes(key)) {
        acc.push(key);
      }
    }
    return acc;
  }, []); // 提取表頭

  return (
    <table>
      <thead>
        <tr>
          {labelList.map((key, index) => (
            <th key={index}>{key}</th>
          ))}
        </tr>
      </thead>
      <tbody>
        {dataSource.map((data, rowIndex) => (
          <tr key={rowIndex}>
            {labelList.map((key, columnIndex) => (
              <!-- 如果是可選屬性,賦予默認(rèn)值 -->
              <td key={columnIndex}>{data[key] ?? '-'}</td>
            ))}
          </tr>
        ))}
      </tbody>
    </table>
  );
}

此時(shí),在 App.tsx 中直接引用 DataTable 組件并傳入 data 數(shù)組,就可以看到表格動(dòng)態(tài)生成如下。

// App.tsx
import DataTable from '@/components/DataTable';

export default function App() {
  const data = [
    { name: 'Alice', city: 'New York' },
    { name: 'Bob', age: 30, city: 'San Francisco' },
    { name: 'Charlie', age: 35, city: 'Chicago' },
    { name: 'David', age: 40, city: 'Los Angeles', num: 0 },
  ];

  return (
    <DataTable dataSource={data} />
  );
}

接下來,就是加上無限滾動(dòng)的效果。

通常來說,可滾動(dòng)表格只會(huì)有一個(gè)表頭,也就是只有一個(gè) thead 部分,并且此處我們把它固定在頂部。再按照上述文字滾動(dòng)的實(shí)現(xiàn)思路,我們只要在一個(gè) table 中準(zhǔn)備兩份相同的 tbody 內(nèi)容,然后給這兩份 tbody 設(shè)置相同的動(dòng)畫即可。

同時(shí),為了限制整體容器的高度,以防用戶在表格位置滾動(dòng)時(shí)感知到突變,造成不好的視覺體驗(yàn),還需要給 table 加一層外部容器。

到此,整個(gè)分析過程就結(jié)束了,DataTable 組件的最終實(shí)現(xiàn)如下:

// DataTable.tsx
export default function DataTable<T extends object>({ dataSource }: { dataSource: Array<T> }) {
  if (!Array.isArray(dataSource) || dataSource.length === 0) {
    return null; // 數(shù)據(jù)源不是數(shù)組或數(shù)組為空,停止操作
  }

  const labelList = dataSource.reduce((acc: any, cur: any) => {
    const keys = Object.keys(cur);
    for (const key of keys) {
      if (!acc.includes(key)) {
        acc.push(key);
      }
    }
    return acc;
  }, []); // 提取表頭

  return (
    <div className={styles.container}>
      <table className={styles.table}>
        <thead>
          <tr>
            {labelList.map((key, index) => (
              <th key={index}>{key}</th>
            ))}
          </tr>
        </thead>
        <tbody className={styles.tbody}>
          {dataSource.map((data, rowIndex) => (
            <tr key={rowIndex}>
              {labelList.map((key, columnIndex) => (
                <td key={columnIndex}>{data[key] ?? '-'}</td>
              ))}
            </tr>
          ))}
        </tbody>
        <tbody className={styles.tbody}>
          {dataSource.map((data, rowIndex) => (
            <tr key={rowIndex}>
              {labelList.map((key, columnIndex) => (
                <td key={columnIndex}>{data[key] ?? '-'}</td>
              ))}
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}
// DataTable.module.scss
@keyframes scroll {
  0% {
    transform: translateY(0);
  }
  100% {
    transform: translateY(-100%);
  }
}

.container {
  height: 160px;
  overflow: hidden;

  .table {
    height: 100%;
    overflow: hidden;
    position: relative;
    background-color: #e6e6e6;
  
    .tbody {
      animation: scroll 4s infinite linear;
    }
  }
}

table {
  width: max-content;
  border-spacing: 0;

  thead {
    height: 30px;
    z-index: 99;
    background-color: #adbcaa;
    position: sticky;
    top: 0;

    tr {
      color: #fff;
      font-weight: bold;
    }
  }

  th,
  td {
    width: max-content;
    padding: 0 8px;
    line-height: 30px;
    text-align: center;
  }
}

然后,刷新頁(yè)面,再看一下頁(yè)面效果,這樣就實(shí)現(xiàn)了。

最后

以上就是基于React實(shí)現(xiàn)無限滾動(dòng)表格的詳細(xì)內(nèi)容,更多關(guān)于React無限滾動(dòng)表格的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • redux的原理、工作流程及其應(yīng)用方式

    redux的原理、工作流程及其應(yīng)用方式

    這篇文章主要介紹了redux的原理、工作流程及其應(yīng)用方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • 使用store來優(yōu)化React組件的方法

    使用store來優(yōu)化React組件的方法

    這篇文章主要介紹了使用store來優(yōu)化React組件的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • 如何去除富文本中的html標(biāo)簽及vue、react、微信小程序中的過濾器

    如何去除富文本中的html標(biāo)簽及vue、react、微信小程序中的過濾器

    這篇文章主要介紹了如何去除富文本中的html標(biāo)簽及vue、react、微信小程序中的過濾器,在vue及react中經(jīng)常會(huì)遇到,今天通過實(shí)例代碼給大家講解,需要的朋友可以參考下
    2018-11-11
  • React?腳手架配置代理完整指南(最新推薦)

    React?腳手架配置代理完整指南(最新推薦)

    本文詳細(xì)介紹了React腳手架配置代理的多種方式,文章還討論了常見問題的解決方案,如跨域問題、WebSocket代理和錯(cuò)誤處理,并提供了生產(chǎn)環(huán)境配置建議和調(diào)試技巧,感興趣的朋友一起看看吧
    2024-12-12
  • react實(shí)現(xiàn)換膚功能的示例代碼

    react實(shí)現(xiàn)換膚功能的示例代碼

    這篇文章主要介紹了react實(shí)現(xiàn)換膚功能的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-08-08
  • 一文詳解React中如何處理高階組件中的錯(cuò)誤

    一文詳解React中如何處理高階組件中的錯(cuò)誤

    在?React?高階組件中處理錯(cuò)誤是確保應(yīng)用程序健壯性和穩(wěn)定性的重要環(huán)節(jié),本文為大家整理了一些處理高階組件中錯(cuò)誤的常見方法,需要的小伙伴可以參考下
    2025-02-02
  • React使用useImperativeHandle自定義暴露給父組件的示例詳解

    React使用useImperativeHandle自定義暴露給父組件的示例詳解

    useImperativeHandle?是?React?提供的一個(gè)自定義?Hook,用于在函數(shù)組件中顯式地暴露給父組件特定實(shí)例的方法,本文將介紹?useImperativeHandle的基本用法、常見應(yīng)用場(chǎng)景,需要的可以參考下
    2024-03-03
  • 詳解React中常見的三種路由處理方式選擇

    詳解React中常見的三種路由處理方式選擇

    這篇文章主要為大家詳細(xì)介紹了React中常見的三種路由處理方式該如何選擇,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • ReactNative列表ListView的用法

    ReactNative列表ListView的用法

    本篇文章主要介紹了ReactNative列表ListView的用法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • Component與PureComponent對(duì)比解析

    Component與PureComponent對(duì)比解析

    這篇文章主要為大家介紹了Component與PureComponent解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-03-03

最新評(píng)論