小程序导航栏与内容区上下联动的实现

前言

之所以把这个功能写出来,是经常看到小伙伴问类似的问题,在这里就详细讲解下整个实现过程,虽然没涉及到什么难点,但希望可以帮助到对这方面还有困惑的朋友。

使用框架及技术

mpvue官方文档

小程序官方文档

源码地址

https://gitee.com/roberthuang123/miniCase.git

实现步骤

<template>
    <div class="nav">
        <scroll-view scroll-x class="tab" :scroll-left="scrollLeft" v-if="getSrcFlag">
            <div class="tab-item" v-for="(item, index) in tabList" :key="index" :class="currentTab===index?'active':''" @tap="switchNav(index)">{{item}}</div>
        </scroll-view>
        <swiper class="swiper"
            :current="currentTab"
            @change="switchTab"
            :style="{height:winHeight+'rpx'}"
        >
            <block v-for="(item, index) in swiperList" :key="index">
                <swiper-item class="item">
                    <scroll-view class="item-box" scroll-y>
                        <div class="box-content" v-for="(itemSecond, indexSecond) in contentList" :key="indexSecond">
                            <image :src="itemSecond.img" class="content-l"/>
                            <div class="content-m">
                                <h3 class="name">{{itemSecond.name}}</h3>
                                <p class="type">{{itemSecond.type}}</p>
                                <p class="desc">{{itemSecond.desc}}</p>
                            </div>
                            <button class="btn" @tap="hint">问TA</button>
                        </div>
                    </scroll-view>
                </swiper-item>
            </block>
        </swiper>
        <div class="loading-container" v-if="!getSrcFlag">
            <loading></loading>
        </div>
    </div>
</template>

<script>
import tools from 'common/js/tools'
import Loading from 'components/loading'
export default {
  name: 'NavBar',
  data () {
    return {
      winHeight: '',
      currentTab: 0,
      scrollLeft: 0,
      tabList: ['健康', '情感', '职场', '育儿', '纠纷', '青葱', '全部', '其他'],
      swiperList: [0, 1, 2, 3, 4, 5, 6, 7],
      contentList: [
        {
          img: '../../static/images/man.png',
          name: '欢颜',
          type: '知名情感博主',
          desc: '134个回答,2234人听过'
        }, {
          img: '../../static/images/man.png',
          name: '欢颜',
          type: '知名情感博主',
          desc: '134个回答,2234人听过'
        }, {
          img: '../../static/images/man.png',
          name: '欢颜',
          type: '知名情感博主',
          desc: '134个回答,2234人听过'
        }, {
          img: '../../static/images/man.png',
          name: '欢颜',
          type: '知名情感博主',
          desc: '134个回答,2234人听过'
        }, {
          img: '../../static/images/man.png',
          name: '欢颜',
          type: '知名情感博主',
          desc: '134个回答,2234人听过'
        }, {
          img: '../../static/images/man.png',
          name: '欢颜',
          type: '知名情感博主',
          desc: '134个回答,2234人听过'
        }, {
          img: '../../static/images/man.png',
          name: '欢颜',
          type: '知名情感博主',
          desc: '134个回答,2234人听过'
        }, {
          img: '../../static/images/man.png',
          name: '欢颜',
          type: '知名情感博主',
          desc: '134个回答,2234人听过'
        }, {
          img: '../../static/images/man.png',
          name: '欢颜',
          type: '知名情感博主',
          desc: '134个回答,2234人听过'
        }, {
          img: '../../static/images/man.png',
          name: '欢颜',
          type: '知名情感博主',
          desc: '134个回答,2234人听过'
        }, {
          img: '../../static/images/man.png',
          name: '欢颜',
          type: '知名情感博主',
          desc: '134个回答,2234人听过'
        }
      ],
      getSrcFlag: false
    }
  },
  components: {
    Loading
  },
  onLoad () {
    const that = this
    wx.getSystemInfo({
      success (res) {
        let clientHeight = res.windowHeight
        let clientWidth = res.windowWidth
        let rpxR = 750 / clientWidth
        let calc = clientHeight * rpxR - 160
        that.winHeight = calc + 80
        console.log(res, calc, that.winHeight)
        that.getSrcFlag = true
      }
    })
  },
  methods: {
    switchTab (e) {
      const that = this
      that.currentTab = e.mp.detail.current
      that.checkTab()
    },
    switchNav (index) {
      const that = this
      that.currentTab = index
      that.checkTab()
    },
    checkTab () {
      const that = this
      if (that.currentTab > 3) {
        that.scrollLeft = 300
      } else {
        that.scrollLeft = 0
      }
    },

    hint () {
      tools.showToast('对案例有任何疑问欢迎在相关文章给我留言~')
    }
  }
}
</script>

顶部导航

使用小程序scroll-view组件实现顶部导航,注意设置两个属性:

  • scroll-x
  • scroll-left

通过事件switchNav(index)来改变currentTab,动态添加class名,当currentTab>3时将scrollLeft设为300px。

内容区

使用小程序swiper组件实现内容区可左右滚动,通过swiper的change事件获取currentTab值

通过读取设备可使用宽高计算出内容区高度:

单个内容区需要上下滚动,依然借助scroll-view组件,设置scroll-y属性实现。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值