vue 微信小程序 ,滑动导航栏内容,自动跳转到对应的导航条位置

74 阅读2分钟

** 例图:**

image.png

<view class="pages">
  <view class="tabs" id="tabs" :style="{{oneFixed}}">
    <block wx:for="{{list}}" wx:key="index">
      <view id="{{index}}" bindtap="tabChange"
        class="tab-item tab-item-{{index}} {{ index== currentIndex ? 'active' : ''}}" data-index="{{index}}"
        data-key="{{ item.key }}">
        {{item.title}}
      </view>
    </block>
  </view>

  <view style="margin-top: 110rpx;" id="cont0" class="cardStyle">
    <view class="tabs_title"> 加盟费用 <text class="note">{{wxSettingData.rateNotes}}</text> </view>
    <view class="answer_box">
      <view class="illustrate">
        <view wx:for="{{franchiseratelists}}" wx:key="index">
          <view style="padding-bottom:20rpx;">
            <view class="{{index == 0 ? 'bold-text' : ''}}">
              <text>{{ item.costName}}</text><text>{{ item.costAmount}}</text>
            </view>
          </view>
        </view>
        <view class="explanation">
          <view>说明:</view>
          <view style="white-space: pre-wrap;">
            {{wxSettingData.rateIllustrate}}
          </view>
        </view>
      </view>
    </view>
  </view>

  <view id="cont1" class="cardStyle">
    <view class="tabs_title"> 加盟要求 <text class="note">{{wxSettingData.joinNotes}}</text> </view>
    <view style="padding-bottom: 20rpx;">
      <view class="answer_box">
        <view class="titles">
          <view class="example">
            <van-icon name="friends-o" color="#3D3D3D" size="20" />
            <text style="font-weight: 600;margin-left: 20rpx;">资质申请人要求</text>
          </view>
        </view>
        <view class="illustrate">
          <view style="white-space: pre-wrap;">{{wxSettingData.applyCondition}}</view>
        </view>
      </view>
      <view class="answer_box">
        <view class="titles">
          <view class="example">
            <van-icon name="gold-coin-o" color="#3D3D3D" size="20" />
            <text style="font-weight: 600;margin-left: 20rpx;">预算要求</text>
          </view>
        </view>
        <view class="illustrate">
          <view style="white-space: pre-wrap;">{{wxSettingData.budgetCondition}}</view>
        </view>
      </view>
      <view class="answer_box">
        <view class="titles">
          <view class="example">
            <van-icon name="shop" color="#3D3D3D" size="20" />
            <text style="font-weight: 600;margin-left: 20rpx;">门店要求</text>
          </view>
        </view>
        <view class="illustrate">
          <view style="white-space: pre-wrap;">{{wxSettingData.storeCondition}}</view>
        </view>
      </view>
    </view>

  </view>

  <view id="cont2" class="cardStyle">
    <view class="tabs_title"> 加盟流程</view>
    <view>
      <van-image src="{{processPic}}" width="100%" height="780" fit="widthFix" />
    </view>
  </view>

  <view id="cont3" class="cardStyle">
    <view class="tabs_title"> 常见问题 <text class="note">{{wxSettingData.faqNotes}}</text> </view>
    <view wx:for="{{getfaqlists}}" wx:key="index" class="answer_box">
      <view class="issue">
        {{item.issue}}
      </view>
      <view class="illustrate" style="font-size: 25rpx;">
        {{item.answer}}
      </view>
    </view>
  </view>
  <view class="btn_box">
    <view class="btn" bindtap="toApplicatFn" data-url="/pagesA/joinApplication/joinApplication"> 快速申请 </view>
  </view>
</view>
const {
  getfranchiseratelist, getWxSetting,getfaqlist,
} = require('../../apis/index');
const util = require("../../utils/util");
Page({
  data: { 
     list: [{
        id: 0,
        title: '加盟费用'
      },
      {
        id: 1,
        title: '加盟要求'
      },
      {
        id: 2,
        title: '加盟流程'
      },
      {
        id: 3,
        title: '常见问题'
      },
    ],  
    navT: 0,  //自定义导航栏距离顶部margin-top
    navH: 0,   //自定义导航栏行高
    oneFixed: '', //吸顶样式
    currentIndex: 0, //当前选中tabs
    franchiseratelists:[],
    getfaqlists:[],
    wxSettingData:{ },
    processPic:'',   
  }, 

  tabChange(e) {
    let selector = '#cont' + e.currentTarget.dataset.index
    let offsetTop = 40 + this.data.navT + this.data.navH
    wx.pageScrollTo({
      offsetTop: -offsetTop,
      selector: selector,
      duration: 0,
      success:function(e){
        console.log("成功",e)
      },
      file:function(e){
        console.log("失败",e)
      }
    })
    this.setData({
      currentIndex: e.currentTarget.dataset.index,
    })
    
    },
  getNav(){
    let that = this
    const res = wx.getMenuButtonBoundingClientRect() 
    that.setData({
      navT: res.top,
      navH: res.height
    })
  }, 
 //获取滚动到顶部
  onPageScroll(event) {
    let that = this 
    let height = this.data.navT + this.data.navH 
    const query = wx.createSelectorQuery()
    for (let item of that.data.list) {
      query.select('#cont' + item.id).boundingClientRect()
    }
 
    query.exec(function (rect) {
      let currentIndex = 0
      for (let i in rect) {
        if (rect[i].top <= (height + 50)) {
          currentIndex = i
        } else {
          break;
        }
      }
      that.setData({
        currentIndex
      })
    })
  },
  
onLoad(optons) {
    let that = this
    that.getNav() 
}, 
 costRequirementsLists(){
   getfranchiseratelist().then(res=>{ 
       this.setData({
         franchiseratelists:  res.data || []
       }) 
   })
 },
 getfaqlists(){
   getfaqlist().then(res=>{  
       this.setData({
         getfaqlists:  res.data || []
       }) 
   })
 },
 getWxSettingData(){
   getWxSetting().then(res=>{  
       this.setData({
        wxSettingData: res.data, 
        processPic: res.data.processPic.replace('?', encodeURIComponent('?')),  
      })    

    })
  },
  toApplicatFn:util.goLink(),
  onShow() {
    this.costRequirementsLists()
    this.getfaqlists()
    this.getWxSettingData()
  },
 
})
.pages {
  box-sizing: content-box;
  background-color: #f7f7f7; 
  padding-bottom: calc(18rpx + 106rpx +  constant(safe-area-inset-bottom)) ;
  padding-bottom: calc(18rpx + 106rpx  + env(safe-area-inset-bottom));
  .bold-text {
    font-weight: 600;
  }
  .cardStyle{  
   width: 679rpx;
   margin: 20rpx auto;    
   background-color: #fff;  
   overflow: hidden;
    border-radius: 10rpx;
  }

.tabs {
  display: flex;
  align-items: center;
  justify-content: space-around; 
  width: 100%;
  height: 92rpx;
  box-sizing: border-box;
  font-size: 29rpx; 
  position: fixed;
  top: 0;
  left: 0;
  z-index: 999;
  background: #fff;
}
.tabs .tab-item {
  color: #3D3D3D;
  display: inline-block;
  position: relative;
  text-align: center;
  font-size: 29rpx;  
}
.tabs .tab-item.active {
  font-size: 29rpx;
  color: #3D3D3D; 
}
.tabs .tab-item:after {
  content: '';
  display: block;
  height: 4rpx;
  width: 0;
  background: #F42E43;
  position: absolute;
  bottom: -18rpx;
  left: 50%;
  border-radius: 100rpx;
  -webkit-transition: all 0.2s ease-in;
  transition: all 0.2s ease-in;
  -webkit-transform: translateX(-50%);
  transform: translateX(-50%);
}
.tabs .tab-item.active:after {
  right: 0;
  width: 100%; 
}
  .explanation {
    padding-bottom: 20rpx;
    font-family: Source Han Sans CN-Regular, Source Han Sans CN;
    font-size: 25rpx
  }

  .tabs_title {
    font-size: 36rpx;
    font-weight: 400;
    margin: 50rpx 30rpx;
    border-bottom: 4rpx solid #e5e5e5;
    padding-bottom: 20rpx;
    margin-bottom: 20rpx;
    .note{
      color: red;
      font-size: 20rpx;
      font-weight: normal; 
    }
  }

  .text_box {
    .titles {
      display: flex;

      .example {
        display: flex;
        justify-content: center;
        margin-top: 10rpx;
        font-size: 37rpx;

      }
    }
  }

  .illustrate {
    background-color: #FFDFDF;
    font-size: 29rpx;
    margin-top: 20rpx;
    padding: 30rpx 16rpx;
    border-radius: 10rpx;
    margin-bottom: 50rpx;
    box-shadow: 10rpx 4rpx 10rpx 0rpx rgba(0,0,0,0.302);
  }

  .answer_box {
    padding: 0 30rpx; 

    .issue {
      font-size: 25rpx;
      font-family: Source Han Sans CN-Bold, Source Han Sans CN;
      font-weight: 700;
      color: #1A1A1A;
      border-bottom: 2rpx solid #F2F2F2;
      padding: 10rpx 0;
    }
  }


  .btn_box{
    display: flex;
    align-items: center;
    justify-content: center;
    position: fixed;
    left: 0;
    bottom: 0rpx;
    width: 100%;
    height: 106rpx;
    line-height: 106rpx;
    padding-top: 18rpx;
    background: #fff; 
    padding-bottom: calc(18rpx + constant(safe-area-inset-bottom)) ;
    padding-bottom: calc(18rpx + env(safe-area-inset-bottom));
  .btn {
    width: 679rpx;
    height: 73rpx;
    line-height: 73rpx;
    font-size: 29rpx;
    text-align: center;
    background: #f7dddd;
    border-radius: 42rpx;
    }
  }
}