【Taro开发】-tabs标签页及子组件的下拉刷新(八)

Taro小程序开发

系列文章的所有文章的目录

【Taro开发】-初始化项目(一)

【Taro开发】-路由传参及页面事件调用(二)

【Taro开发】-taro-ui(三)

【Taro开发】-带token网络请求封装(四)

【Taro开发】-自定义导航栏NavBar(五)

【Taro开发】-formData图片上传组件(六)

【Taro开发】-封装Form表单组件和表单检验(七)

【Taro开发】-tabs标签页及子组件的下拉刷新(八)

【Taro开发】-简易的checkBoxGroup组件(九)

【Taro开发】-页面生成二维码及保存到本地(十)

【Taro开发】-宣传海报,实现canvas实现圆角画布/图片拼接二维码并保存(十一)

【Taro开发】-分享给好友/朋友圈(十二)

【Taro开发】-小程序自动打包上传并生成预览二维码(十三)

【Taro开发】-全局自定义导航栏适配消息通知框位置及其他问题(十四)



前言

基于Taro的微信小程序开发,主要组件库为Taro-ui

实现效果:
1.tab栏在滚动后吸顶
2.列表触底时能加载下一页内容,提示加载中,到底提示没有了
在这里插入图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

一、tab栏吸顶效果

小程序的吸顶效果只需要设置position

.tabRow {
      position: sticky;
      top:0;
      z-index: 100;
 }

注意:当内外两层的posotion都为sticky可能出出现抖动,可在外层叠加一层view挡住抖动

二、标签页触底加载更多

1.tabs组件

由于taro-ui的tabs标签页是在页面挂载后全部一次加载出来,且高度之间相互影响,不是独立的,同时我的每个便签页都是不同的一套逻辑,需是不同的子组件,因此自己简单封装了一个tabs组件。
后续兼容侧边标签页type:"vertical " | "horizontal "
在这里插入图片描述

// tabs.jsx
import { Component } from "react";
import { View, Text} from "@tarojs/components";
import "./index.scss";

class Tabs extends Component {
  constructor() {
    super();
    this.state = {
      current: 0
    };
  }

  componentWillMount() {
    if (this.props.current) this.setState({ current: this.props.current });
  }

  componentWillUpdate(nextProps, nextState) {
    if (nextProps.current !== this.props.current) {
      this.setState({ current: nextProps.current });
    }
  }
  border = index => {
    if (index === this.state.current || 0) {
      return "normal active";
    } else if (index === this.state.current - 1) {
      return "normal borderBtmRight ";
    } else if (index === this.state.current + 1) {
      return "normal borderTopRight";
    } else {
      return "normal";
    }
  };
  render() {
    const { tabList, onClick, type, className, style } = this.props;
    const { current } = this.state;
    return (
      <View
        className={
          (type === "vertical" ? "vertical " : "horizontal ") +
          (className || "")
        }
        style={style}
      >
        <View className={"tabs"}>
          {tabList &&
            tabList.map((item, index) => {
              return (
                <View className="tabsPack">
                  <View
                    key={index}
                    className={this.border(index)}
                    onClick={() => onClick && onClick(index)}
                  >
                    <Text>{item.title}</Text>
                    <View
                      className={
                        index === current || 0
                          ? "tabsLine tabsLineActive"
                          : "tabsLine"
                      }
                    ></View>
                  </View>
                </View>
              );
            })}
        </View>
        <View className="tabMes">{this.props.children}</View>
      </View>
    );
  }
}
export default Tabs;

// index.scss
@import "@/styles/variables.scss";

.vertical {
  flex: 1;
  margin-top: $spacing-base;
  display: flex;
  flex-direction: row;

  .tabs {
    width: 188px;
    background-color: $color-bg;

    .normal {
      height: 88px;
      display: flex;
      align-items: center;
      justify-content: center;
      color: $color-text-9;
    }

    .active {
      background-color: $color-white;
    }
  }

  .tabMes {
    flex: 1;
    background-color: $color-white;
  }
}

.horizontal {
  .tabs {
    display: flex;
    flex-direction: row;
    align-items: center;
    justify-content: space-between;
    padding: 26px 50px 26px;

    .normal {
      color: $color-text-9;
      display: flex;
      flex-direction: column;
      align-items: center;

      .tabsLine {
        background: $color-default-dark;
        width: 48px;
        height: 4px;
        margin-top: 4px;
        transform: scaleX(0);
        transition: all 0.15s;
      }

      .tabsLineActive {
        transform: scaleX(1) !important;
      }
    }

    .active {
      font-size: $font-size-xxl;
      color: $color-default-dark;
      font-weight: bold;
    }
  }
}

2.tabs组件的使用及页面子组件

由于我的tab栏需要吸顶,所以我将tab栏和标签页拆开,不丢在一起

//Page state
reachBottom: false,
hasMore: true
//render
		<Tabs
            className="tabRow"//其他样式,实现吸顶效果
            tabList={tabList}
            current={tabCurrent}
            onClick={i => this.setState({ tabCurrent: i, hasMore: true })}//hasMore为后续加载更多时的一个判断
          />
          {tabList[tabCurrent].key === "batch" && (
            <Batch
              ref={c => (this.batch = c)}//后续调用子组件实例
              ...//其他属性
            />
          )}
          ...//其他标签页子组件
          {reachBottom && (
            <AtActivityIndicator
              className="trace-bottom-text"
              isOpened={reachBottom}
              content="加载中..."
            />
          )}
          {!hasMore && <View className="trace-bottom-text">没有更多了~</View>}

页面子组件Batch

componentDidMount() {
    const { ref } = this.props;
    ref && ref(this);
}

//调用接口获取下一页数据
getList = async (ope) => {//ope为操作,'next'为获取下一页,否则为第一页,为初始化/刷新时使用
    const { page, list } = this.state;
    let size = 10;
    let params = {
      page: ope === "next" ? page + 1 : 1,
      size,
    };
    let res = await service.getPage( params);
    if (!res?.failed) {
      this.setState({
        page: ope === "next" ? page + 1 : 1,
        list: ope === "next" ? [...list, ...res?.content] : res?.content
      });
      if ((ope === "next" ? page + 1 : 1) * size < res?.totalElements)//判断是否还有数据,并返回
        return true;
      else return false;
    } else {
      Taro.atMessage({
        type: "error",
        message: `${res?.message}`
      });
      return true;
    }
  };
  

页面事件

async onReachBottom() {
    const { areaId, hasMore, tabCurrent, list, swiperCurrent } = this.state;
    if (hasMore) {
      this.setState({ reachBottom: true });
      let longList;
      //根据当前不同的标签页获得相对应子组件的实例
      longList = this[tabList[tabCurrent]?.key];
      let isHasMore = await longList.getList("next");
      this.setState({ reachBottom: false, hasMore: isHasMore });
    }
  }

目前还有一点不伤大雅的小问题,即标签页的列表长度过短时,无法触发到触底事件,所以显示不了没有更多的提示,如果有解决的方法,欢迎交流

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
要在 Taro 中实现下拉刷新功能,你需要使用 Taro 提供的 `ScrollView` 组件,并在其中使用 `onScrollToLower` 属性来监听到达底部事件。以下是一个简单的示例代码: ```jsx import { ScrollView, View } from '@tarojs/components'; import Taro from '@tarojs/taro'; class MyPage extends Taro.Component { constructor(props) { super(props); this.state = { dataList: [], page: 1, size: 10, }; } componentDidMount() { // 面加载时,执行一次下拉刷新 this.onPullDownRefresh(); } async onPullDownRefresh() { // 模拟异步加载数据 const newData = await this.loadData(this.state.page, this.state.size); this.setState({ dataList: newData, page: 1, }); Taro.stopPullDownRefresh(); } async onReachBottom() { // 模拟异步加载数据 const newData = await this.loadData(this.state.page + 1, this.state.size); this.setState({ dataList: [...this.state.dataList, ...newData], page: this.state.page + 1, }); } async loadData(page, size) { // 模拟异步加载数据 return new Promise((resolve) => { setTimeout(() => { const newData = Array.from({ length: size }, (_, i) => ({ id: (page - 1) * size + i, text: `数据${(page - 1) * size + i}` })); resolve(newData); }, 1000); }); } render() { return ( <ScrollView scrollY style={{ height: '100vh' }} onScrollToLower={this.onReachBottom}> <View> {this.state.dataList.map((data) => ( <View key={data.id}>{data.text}</View> ))} </View> </ScrollView> ); } } ``` 在上面的代码中,我们通过 `ScrollView` 组件来实现滚动,并通过 `onScrollToLower` 属性来监听到达底部事件,然后在事件回调函数中加载更多数据并更新状态。同时,我们也重写了 `onPullDownRefresh` 方法,来实现下拉刷新功能。在该方法中,我们模拟了异步加载数据的过程,并在加载完成后通过 `setState` 方法来更新状态,最后调用 `Taro.stopPullDownRefresh()` 方法来停止下拉刷新动画。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

-雾里-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值