支付宝小程序tabs标签

本文主要针对支付宝小程序的tabs标签页切换进行自定义。
大家可以发现官方文档是有点小缺陷的,可以支持页面左右滑动,但是要固定高度而且要写到acss样式文件里。不支持页面滑动的话高度可以自适应。但是还是有点小问题的哦。况且不支持滑动显得还是不是很友好。
在这里插入图片描述
下面粘上我的代码。自定义实现tabs页切换和页面左右切换。

page.axml

<scroll-view scroll-x="true" class="nav" scroll-with-animation="{{true}}">
  <block a:for="{{tabs}}" a:key="{{index}}">
    <view class="nav-item">
      <view class="{{activeTab == index ?'active':''}}" data-current="{{index}}" onTap="handleTabClick">{{item.title}}</view>
    </view>
  </block> 
</scroll-view>
<swiper class="tab-box " current="{{activeTab}}" duration="300" onChange="handleTabChange"> 
  <swiper-item a:for="{{tabsType}}" a:key="{{index}}" class="tab-content">
    <contract-item ref = "{{item.ref}}" status = "{{item.status}}" onShowNullData = "onShowNullData"/>
  </swiper-item>
</swiper>

page.acss

.nav {
  height: 80rpx;
  width: 100%;
  box-sizing: border-box;
  overflow: hidden;
  line-height: 76rpx;
  background: #FFFFFF;
  font-size: 14px;
  white-space: nowrap;
  display: flex;
  box-sizing: border-box;
}
.nav::-webkit-scrollbar {
  display: none;
}
.nav-item {
  flex-shrink: 0;
  -webkit-box-flex: 0;
  flex-grow: 0;
  width: 33.333333%;
  height: 76rpx;
  text-align: center;
}
.active{
  display: inline-block;
  color:#4884EE;
  border-bottom: 2px solid #4884EE;
}
.tab-box{
  height: 750px !important;
  background:#F5F5F5;
  box-sizing: border-box;
}
.tab-content{
  margin-top: 1rpx;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}

page.json

{
  "defaultTitle": "订单管理",
  "pullRefresh": true,
  "usingComponents": {
    "contract-item": "./contract-item/contract-item"
  }
}

page.js

Page({
  data: {
    tabsType: [//标签数组
      { ref: "page0",status: '1'},
      { ref: "page1",status: '2'},
      { ref: "page2",status: '3'}
    ],
    loadFlags: 0x0000,//各tab是否加载
    tabs: [
      { title: '待审核' },
      { title: '已通过' },
      { title: '已拒绝' }
    ],
    activeTab: 0,
    footer: false,
  },
  page0(ref) {
    this.page0 = ref;
  },
  page1(ref) {
    this.page1 = ref;
  },
  page2(ref) {
    this.page2 = ref;
  },
  onLoad() {
    this.setData({
      loadFlags: 0x0001
    });
  },
  onPullDownRefresh() {
    this.onRefresh();
  },
  onReachBottom() {
    if (this.data.activeTab === 0) {
      this.page0.onLoadMore();
    }else if(this.data.activeTab === 1){
      this.page1.onLoadMore();
    }else{
      this.page2.onLoadMore();
    }
  },
  //标签切换
  handleTabClick(e) {
    this.setData({
      activeTab: e.currentTarget.dataset.current
    })
    this.onCalculate();
  },
  //手势滑动
  handleTabChange(e) {
    console.log(e)
    var cur = e.detail.current; 
    if (this.data.activeTab == cur) {
      return false;
    } else {
      this.setData({
        activeTab: cur
      })
    }
    this.onCalculate();
  },
  //我在这里注释一下,怕以后在看的时候自己再费时间理解
  onCalculate: function () {
    //次方运算 1 2 4
    let tempFlag = Math.pow(2, this.data.activeTab);
    // 按位与
    // 0x0001 & 0x0001 = 0x0001 1 已加载
    // 0x0001 & 0x0010 = 0x0000 0 未加载
    // 0x0001 & 0x0100 = 0x0000 0 未加载
    let hasLoaded = this.data.loadFlags & tempFlag;
    if (!hasLoaded) {//未加载
      this.onRefresh();//加载数据
      //获取当前加载状态 0x0001 已加载
      let curFlags = this.data.loadFlags;
      //修改状态
      this.setData({
        // 按位或
        // 0x0001 | 0x0010 = 0x0011
        // 0x0001 | 0x0100 = 0x0111
        loadFlags: (curFlags | tempFlag),
      });
    }
  },

  onRefresh: function () {
    if (this.data.activeTab === 0) {
      this.page0.onRefresh();
    }else if(this.data.activeTab === 1){
      this.page1.onRefresh();
    }else{
      this.page2.onRefresh();
    }
  },

contract-item.axml

<view>
	<scroll-view scroll-y onScrollToLower="onLoadMore">
		<list>
			<block a:for="{{list}}">
				<list-item
					align="{{item.align}}"
					index="{{index}}"
					onClick="onItemClick"
					key="items-{{index}}"
					last="{{index === (list.length - 1)}}"
          data-id="{{item.id}}"
				>
					<view></view>
			 </list-item>
			</block>
		</list>
	</scroll-view>
</view>

contract-item.acss

.am-list-item {
  padding: 0;
}

.am-list-content {
  padding: 0;
}

contract-item.js

const api = require('../../../../request.js')

import pageStatus, { onRetry } from '../../../../page-status/page-status.js'

const app = getApp()

Component({
  mixins: [],
  data: {
    page0: null,
    page1: null,
    page2: null,
    list: [],
    pageNum: 1,
    pageSize: 10,
    total: 0,
    scrollHeight:my.getSystemInfoSync().windowHeight-44,
  },
  props: {
    status: '1',
    onShowNullData: () => {},
  },
  didMount() {
    if (this.props.status === '1') {
      this.onRefresh();
    }
  },
  didUpdate() {},
  didUnmount() {},
  methods: {
    /* 下拉刷新 */
    onRefresh: function () {
      this.setData({
        pageNum: 1
      })
      this.onFetchData();
    },
    // 上拉加载
    onLoadMore: function() {
      console.log('上啦加载了');
      // 不分页不加载、加载完毕不加载
      if (this.data.total > this.data.list.length) {
        this.setData({
          pageNum: this.data.pageNum + 1
        })
        this.onFetchData();
      }
    },
    // 获取数据
    onFetchData: function() {
      const currentPageStatus = pageStatus(this);
      my.showNavigationBarLoading();
      if (app.globalData.networkFailed) {//网络监听
        currentPageStatus.nonetwork();
        my.stopPullDownRefresh();
        my.hideNavigationBarLoading();
      } else {
        var url = `/dayan/scf/user/contract/list/${this.props.status}?pageNum=${this.data.pageNum}&pageSize=${this.data.pageSize}`
        api.http(url,'GET',{},success=>{
          if (this.data.pageNum === 1) {//第一页
            this.setData({
              list: success.data,
              total: success.total
            })
          } else {//第n页
            this.setData({
              list: this.data.list.concat(success.data),
              total: success.total
            })
          }
          if (this.data.list.length === 0) {
            currentPageStatus.empty();
          } else {
            currentPageStatus.finish();
          }
          my.hideNavigationBarLoading();
          this.onShowNullData();
        }, fail=>{
          currentPageStatus.error();
          my.hideNavigationBarLoading();
        });
      }
    },
    onItemClick(e) {
      let id = e.target.dataset.id;
      let dest = `./contract-detail/contract-detail?id=${id}`;
      my.navigateTo({
        url: dest,
      })
    },

    onRetry() {
      console.log('刷新网络操作')
      this.onRefresh();
    },
  },
});

contract-item.json

{
  "component": true,
  "usingComponents": {
    "list-item": "mini-antui/es/list/list-item/index",
    "list": "mini-antui/es/list/index"
  }
}

component的js文件数据部分(onFetchData)是我自己定义的缺省页面及网络状态监测,请使用的小主自行修改为自己封装的内容

觉得有帮助的给小姐姐带个赞吧。感谢~

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值