小程序 选项卡 滑动 内容滑动切换

      <view class="tab-page-root">
        <view class="tabbar-header flex_align-center">
          <view v-for="(item, i) in tabs" @tap="tabTap(i)" class="flex1" :key="item">{{ item }}</view>
        </view>
        <view :style="{ left: tabLineLeft + 'px' }" class="tabbar-line"></view>
        <view
          class="tabbar-content"
          :style="'transform:translateX(' + xPercent + '%);transition:transform ' + pageDuration + 'ms;'"
          @touchstart="touchstart"
          @touchmove="touchmove"
          @touchend="touchend"
        >
          <view v-for="(item, i) in tabs" :key="item" :style="'transform:translateX(' + i * 100 + '%);height:' + height + 'px;'" class="tabbar-page">
            <!-- <slot name="page" :i="i" :pageData="pageData"></slot> -->
            <view class="item0" v-if="i == 0"><view v-for="(item, index) in list1" :key="index">321232312146465458574888784654655654</view></view>

            <view class="item1" v-if="i == 1"><view v-for="(item, index) in list2" :key="index">321232312146465458574888784654655654</view></view>

            <view class="item2" v-if="i == 2"><view v-for="(item, index) in list3" :key="index">321232312146465458574888784654655654</view></view>

            <view class="item3" v-if="i == 3"><view v-for="(item, index) in list4" :key="index">321232312146465458574888784654655654</view></view>
          </view>
        </view>
const safeAreaWidth = uni.getSystemInfoSync().safeArea.width;
let tabbarLineWidth,
  yAxisGap = 8;
// #ifdef H5
yAxisGap = 6;
// #endif
export default {
  components: {
    // pag
  },
  data() {
    let tabs = ['作品', '喜欢', '收藏', '评论'];
    let pageData = [['AAA', 'BBBB'], ['CCC', 'DD']];
    return {
      tabs,
      pageData,
      tabIndex: 0,
      xPercent: 0,
      startPageX: 0,
      startPageY: 0,
      yScrollTimes: 0,
      yScrolling: false,
      positive: 1,
      pageDuration: 0,
      tabLineLeft: safeAreaWidth / tabs.length - 17,
      height: 0,
      list1: [{}, {}, {}, {}, {}, {}, {}, {}],
      list2: [{}, {}, {}],
      list3: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}],
      list4: [{}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}, {}]
    };
  },
  mounted() {
    uni.createSelectorQuery()
      .in(this)
      .select('.tabbar-line')
      .boundingClientRect(data => {
        // data - 各种参数
        tabbarLineWidth = data.width;
        this.tabLineLeft = (safeAreaWidth / this.tabs.length - tabbarLineWidth) / 2;
      })
      .exec();
    this.getheight();
  },
  methods: {
    tabSwitch(i) {
      if (i == 1) {
        //注意:以下是tab页加载数据的方式
        this.lists.splice(1, 1, ['GGGG']);
      }
    },

    getheight() {
      console.log(this);
      let that = this;
               let theNode = uni.createSelectorQuery().select('.item'+ that.tabIndex);
          theNode.boundingClientRect((data)=>{
            this.height = data.height
          console.log(this);
                console.log(data)
          }).exec()
    },
    tabTap(i) {
      this.getheight();

      if (this.tabIndex != i) {
        this.pageDuration = 0;
        this.xPercent = -i * 100;
        this.tabIndex = i;
        this.tabLineLeft = ((i + 1 / 2) * safeAreaWidth) / this.tabs.length - tabbarLineWidth / 2;
        this.loadTabPage();
      }
    },
    touchstart(e) {
      this.startPageX = e.changedTouches[0].pageX;
      this.startPageY = e.changedTouches[0].pageY;
      this.startXPercent = this.xPercent;
    },
    touchmove(e) {
      this.yScrollTimes++;
      if (this.yScrollTimes == 1 && Math.abs(e.changedTouches[0].pageY - this.startPageY) > yAxisGap) {
        this.yScrolling = true;
      }
      if (this.yScrolling) return;
      this.pageDuration = 0;
      const relativeXPercent = ((e.changedTouches[0].pageX - this.startPageX) * 100) / safeAreaWidth;
      if (this.relativeXPercent < relativeXPercent) {
        this.positive = -1;
      } else {
        this.positive = 1;
      }
      const xPercent = relativeXPercent + this.startXPercent;
      if (xPercent >= 0) {
        this.xPercent = 0;
      } else if (xPercent <= (1 - this.tabs.length) * 100) {
        this.xPercent = (1 - this.tabs.length) * 100;
      } else {
        this.xPercent = xPercent;
      }
      this.relativeXPercent = relativeXPercent;
    },
    touchend() {
      if (-this.xPercent % 100 < 10 || (this.relativeXPercent < 0 && this.positive < 0)) {
        this.pageDuration = 80;
        this.tabIndex = Math.floor(-this.xPercent / 100);
      } else if (-this.xPercent % 100 > 90 || (this.relativeXPercent > 0 && this.positive > 0)) {
        this.pageDuration = 80;
        this.tabIndex = Math.floor(-this.xPercent / 100 + 1);
      } else {
        this.pageDuration = 300;
        this.tabIndex += this.positive;
        this.tabLineLeft = ((this.tabIndex + 1 / 2) * safeAreaWidth) / this.tabs.length - tabbarLineWidth / 2;
        this.loadTabPage();
      }
      this.xPercent = -this.tabIndex * 100;
      this.yScrolling = false;
      this.yScrollTimes = 0;
    },
     // 切换选项卡的  相应函数
    loadTabPage() {
    // 点击选项卡 重新获取高度
      this.getheight();
      // this.$emit('tabSwitch', this.tabIndex);
    }
  }
};

 注意: calss命名 这个跟获取高度有重要关系 !!!

.tab-page-root {
  position: absolute;
  width: 100%;
}

.tabbar-header {
  text-align: center;
  line-height: 72upx;
}

.tabbar-line {
  position: relative;
  left: 96upx;
  width: 80rpx;
  height: 8rpx;
  background-color: #000000;
  transition: left 300ms;
}

.tabbar-content {
  min-height: calc(100% - 83upx);
}

.tabbar-page {
  position: absolute;
  width: 100%;
  height: 100%;
  overflow-y: auto;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
微信小程序的tabbar切换是通过在app.json文件中配置tabBar属性来实现的。在tabBar属性中,我们可以设置position为bottom或top来指定tabBar的位置。tabBar中的list是一个数组,可以配置最少2个、最多5个tab,按数组的顺序排序。每个tab可以设置pagePath来指定页面路径,text来设置tab上显示的文字,iconPath和selectedIconPath来设置未选择时和选中时的图标路径,color和selectedColor来设置未选择时和选中时的文本颜色。在渲染底部tabBar时,会显示文本和图标,而在渲染顶部tabBar时,只会显示文本。需要注意的是,顶部的tabBar目前仅微信小程序上支持。当切换tabBar页面时,会触发每个页面的onShow生命周期,而不会再触发onLoad。\[1\]\[2\]\[3\] #### 引用[.reference_title] - *1* [【微信小程序】页面tabBar切换、下拉刷新](https://blog.csdn.net/yzq0820/article/details/126715814)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [【微信小程序入门到精通】— 微信小程序实现多页面切换(tabBar)](https://blog.csdn.net/fsadagds/article/details/127598366)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值