移动端的下拉刷新和上滑加载

本文叙述了在mobile端实现下拉刷新和上拉加载的经典功能。功能是通过antd-mobile组件实现的,欢迎大家在评论区提出意见,谢谢!

1. 下拉刷新

PullToRefresh 组件是 Ant Design Mobile V2(antd-mobile-v2)中用于下拉刷新的组件。它提供了一种用户友好的方式来触发数据的更新,通常用于移动端应用的列表页面。

API 和原理:

API

  • onRefresh (function): 在下拉刷新时触发的回调函数。
  • direction (string): 指定下拉刷新的方向,可以是 down(默认)或 up
  • indicator (object): 自定义提示文案的配置。
  • distanceToRefresh (number): 触发刷新的距离,默认为 50px
  • damping (number): 阻尼系数,值越大表示阻尼越小,可以通过调整这个值改变下拉刷新的感觉。
  • getScrollContainer (function): 获取滚动容器的函数,用于指定滚动的容器,默认为 window。
  • prefixCls (string): 样式类名的前缀。

原理

PullToRefresh 主要通过监听用户的下拉手势,当下拉的距离达到一定值时,触发刷新操作。同时,在刷新过程中,会显示相应的提示文案或图标,提供良好的用户体验。

使用示例:

jsx 复制代码
import React, { useState, useEffect } from 'react';
import { PullToRefresh, ListView } from 'antd-mobile-v2';

const MyList = () => {
  const [dataSource, setDataSource] = useState(new ListView.DataSource({
    rowHasChanged: (row1, row2) => row1 !== row2,
  }));
  const [refreshing, setRefreshing] = useState(false);

  const onRefresh = () => {
    // 模拟异步数据加载
    setRefreshing(true);
    fetchData().then(() => {
      setRefreshing(false);
    });
  };

  useEffect(() => {
    // 初始化数据
    fetchData();
  }, []);

  const fetchData = async () => {
    // 模拟异步数据加载
    const data = await fetchDataFromAPI();
    setDataSource(dataSource.cloneWithRows(data));
  };

  const renderRow = (rowData, sectionID, rowID) => (
    <div key={rowID}>{rowData}</div>
  );

  return (
    <ListView
      dataSource={dataSource}
      renderRow={renderRow}
      renderFooter={() => <div>Loading...</div>}
      renderHeader={() => (
        <PullToRefresh
          onRefresh={onRefresh}
          distanceToRefresh={50}
          refreshing={refreshing}
        />
      )}
    />
  );
};

export default MyList;

详细解释

逐步解释这段代码:

1. 导入语句:

jsx 复制代码
import React, { useState, useEffect } from 'react';
import { PullToRefresh, ListView } from 'antd-mobile-v2';

解释:从 'antd-mobile-v2' 库和 React 中导入必要的组件。导入的组件包括 PullToRefreshListView

2. 函数组件声明:

jsx 复制代码
const MyList = () => {
  // 状态钩子
  const [dataSource, setDataSource] = useState(new ListView.DataSource({
    rowHasChanged: (row1, row2) => row1 !== row2,
  }));
  const [refreshing, setRefreshing] = useState(false);

解释:声明一个名为 MyList 的函数组件。使用 useState 钩子来管理组件的状态。定义了两个状态变量:dataSource 用于管理 ListView 的数据源,refreshing 用于追踪刷新状态。

3. onRefresh 函数:

jsx 复制代码
  const onRefresh = () => {
    // 模拟异步数据加载
    setRefreshing(true);
    fetchData().then(() => {
      setRefreshing(false);
    });
  };

解释:定义 onRefresh 函数,模拟异步数据加载过程。将 refreshing 状态设置为 true,调用 fetchData 函数,然后一旦数据获取完成,将 refreshing 设置回 false

4. 用于初始数据获取的 useEffect:

jsx 复制代码
  useEffect(() => {
    // 初始化数据
    fetchData();
  }, []);

解释:使用 useEffect 钩子在组件挂载时执行初始数据获取。通过调用 fetchData 函数,使用空依赖数组确保它在组件初始化时只运行一次。

5. fetchData 函数:

jsx 复制代码
  const fetchData = async () => {
    // 模拟异步数据加载
    const data = await fetchDataFromAPI();
    setDataSource(dataSource.cloneWithRows(data));
  };

解释:定义 fetchData 函数,负责从 API(这里是模拟的)获取数据。使用 await 处理异步调用,通过使用新获取的数据克隆更新 dataSource 状态。

6. renderRow 函数:

jsx 复制代码
  const renderRow = (rowData, sectionID, rowID) => (
    <div key={rowID}>{rowData}</div>
  );

解释:定义 renderRow 函数,负责渲染 ListView 中的每一行。接收 rowDatasectionIDrowID,返回一个带有 rowData 内容的 div 元素。

7. 返回 JSX 结构:

jsx 复制代码
  return (
    <ListView
      dataSource={dataSource}
      renderRow={renderRow}
      renderFooter={() => <div>Loading...</div>}
      renderHeader={() => (
        <PullToRefresh
          onRefresh={onRefresh}
          distanceToRefresh={50}
          refreshing={refreshing}
        />
      )}
    />
  );
};

解释:组件的主要渲染部分。返回一个具有指定属性的 ListView 组件,包括 dataSourcerenderRowrenderFooterrenderHeaderrenderHeader 包含一个 PullToRefresh 组件,在下拉时触发 onRefresh 函数。

8. 导出组件:

jsx 复制代码
export default MyList;

解释:导出 MyList 组件,以便在应用程序的其他部分中使用。

2. 上滑加载

若您想同时实现下拉刷新和上滑加载,可以结合 ListView 提供的 onEndReached 回调和 renderFooter 来实现上滑加载的效果。以下是一个基本的实现示例:

jsx 复制代码
import React, { useState, useEffect } from 'react';
import { PullToRefresh, ListView } from 'antd-mobile-v2';

const MyList = () => {
  const [dataSource, setDataSource] = useState(new ListView.DataSource({
    rowHasChanged: (row1, row2) => row1 !== row2,
  }));
  const [refreshing, setRefreshing] = useState(false);
  const [isLoadingMore, setIsLoadingMore] = useState(false);

  const onRefresh = () => {
    // 模拟异步数据加载
    setRefreshing(true);
    fetchData().then(() => {
      setRefreshing(false);
    });
  };

  const onEndReached = () => {
    // 防止重复触发
    if (!isLoadingMore) {
      setIsLoadingMore(true);
      // 模拟异步加载更多数据
      fetchMoreData().then(() => {
        setIsLoadingMore(false);
      });
    }
  };

  useEffect(() => {
    // 初始化数据
    fetchData();
  }, []);

  const fetchData = async () => {
    // 模拟异步数据加载
    const data = await fetchDataFromAPI();
    setDataSource(dataSource.cloneWithRows(data));
  };

  const fetchMoreData = async () => {
    // 模拟异步加载更多数据
    const moreData = await fetchMoreDataFromAPI();
    setDataSource(dataSource.cloneWithRows([...dataSource._dataBlob.s1, ...moreData]));
  };

  const renderRow = (rowData, sectionID, rowID) => (
    <div key={rowID}>{rowData}</div>
  );

  const renderFooter = () => (
    <div style={{ padding: 30, textAlign: 'center' }}>
      {isLoadingMore ? 'Loading more...' : ''}
    </div>
  );

  return (
    <ListView
      dataSource={dataSource}
      renderRow={renderRow}
      renderFooter={renderFooter}
      renderHeader={() => (
        <PullToRefresh
          onRefresh={onRefresh}
          distanceToRefresh={50}
          refreshing={refreshing}
        />
      )}
      onEndReached={onEndReached}
      onEndReachedThreshold={10}
    />
  );
};

export default MyList;

详细解释

继续解释这段代码:

1. 新增状态钩子:

jsx 复制代码
  const [isLoadingMore, setIsLoadingMore] = useState(false);

解释:新增了一个状态变量 isLoadingMore,用于追踪是否正在加载更多数据。

2. onEndReached 函数:

jsx 复制代码
  const onEndReached = () => {
    // 防止重复触发
    if (!isLoadingMore) {
      setIsLoadingMore(true);
      // 模拟异步加载更多数据
      fetchMoreData().then(() => {
        setIsLoadingMore(false);
      });
    }
  };

解释:定义 onEndReached 函数,用于在列表滚动到底部时加载更多数据。通过检查 isLoadingMore 变量,防止重复触发加载更多。

3. fetchMoreData 函数:

jsx 复制代码
  const fetchMoreData = async () => {
    // 模拟异步加载更多数据
    const moreData = await fetchMoreDataFromAPI();
    setDataSource(dataSource.cloneWithRows([...dataSource._dataBlob.s1, ...moreData]));
  };

解释:定义 fetchMoreData 函数,模拟异步加载更多数据。将新获取的数据与当前数据合并,并通过 cloneWithRows 更新 dataSource

4. renderFooter 函数:

jsx 复制代码
  const renderFooter = () => (
    <div style={{ padding: 30, textAlign: 'center' }}>
      {isLoadingMore ? 'Loading more...' : ''}
    </div>
  );

解释:定义 renderFooter 函数,用于渲染列表底部。根据 isLoadingMore 变量的值,显示加载更多的提示信息。

5. 返回 JSX 结构:

jsx 复制代码
  return (
    <ListView
      dataSource={dataSource}
      renderRow={renderRow}
      renderFooter={renderFooter}
      renderHeader={() => (
        <PullToRefresh
          onRefresh={onRefresh}
          distanceToRefresh={50}
          refreshing={refreshing}
        />
      )}
      onEndReached={onEndReached}
      onEndReachedThreshold={10}
    />
  );
};

解释:在 ListView 中添加了 onEndReachedonEndReachedThreshold 属性,用于触发加载更多数据的逻辑。renderFooter 用于显示底部加载更多的提示信息。整个组件现在支持上拉加载更多的功能。

相关推荐
柏箱1 小时前
PHP基本语法总结
开发语言·前端·html·php
赛男丨木子丿小喵14 小时前
visual studio2022添加新项中没有html和css
css·html·visual studio
太阳花ˉ17 小时前
html+css+js实现step进度条效果
javascript·css·html
小白学习日记17 小时前
【复习】HTML常用标签<table>
前端·html
道爷我悟了19 小时前
Vue入门-指令学习-v-html
vue.js·学习·html
l1x1n01 天前
No.3 笔记 | Web安全基础:Web1.0 - 3.0 发展史
前端·http·html
神之王楠1 天前
如何通过js加载css和html
javascript·css·html
茶卡盐佑星_1 天前
meta标签作用/SEO优化
前端·javascript·html
金灰1 天前
HTML5--裸体回顾
java·开发语言·前端·javascript·html·html5
Zheng1131 天前
【可视化大屏】将柱状图引入到html页面中
javascript·ajax·html