欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

微信小程序 ---制作一个类似头条的滑动tab导航栏

程序员文章站 2024-02-11 13:36:16
...

效果图:
微信小程序 ---制作一个类似头条的滑动tab导航栏

使用页面wxml

<!-- 顶部滑动导航栏组件 -->
<slideNav navList="{{ navList }}" fontSize="{{ 28 }}" padding="{{ 20 }}" bindtabFun="tabFun"></slideNav>

使用页面json

{
  "usingComponents": {
    "slideNav": "/component/slideNav/slideNav"
  }
}

使用页面js

// page/slideNav/slideNav.js
Page({

  /**
   * 页面的初始数据
   */
  data: {
    navList: ['关注', '推荐', '抗击肺炎', '广州', '热点', '影视', '视频', '军事', '在家上课', '动漫', '漫画', '娱乐', '国际', '科技', '正能量', '音乐', '图片', '科技', '财经', '健康', '手机', '搞笑', '法制', '职场', '情感','网球'],
  },

  tabFun(e) {
    console.log(e.detail);
  },
})

下面是组件部分

组件wxml

<scroll-view scroll-x="{{ true }}" scroll-left="{{ navLeft }}" scroll-with-animation="{{ true }}">
  <view class="nav_container">
    <block wx:for="{{ navList }}" wx:key="index">
      <view class="nav_option {{ subscript == index ? 'nav_on' : '' }}" style="padding: 0 {{ padding }}rpx; font-size: {{ fontSize }}rpx;" catchtap="tabFun" data-text="{{ item }}" data-subscript="{{ index }}">{{ item }}</view>
    </block>

    <view class="nav_line" style="width: {{ lineW }}px; transform: translateX({{ lineLeft }}px);">
      <view></view>
    </view>
  </view>
</scroll-view>

组件wxss

scroll-view {
  width: 100%;
}

.nav_container {
  display: inline-block;
  white-space: nowrap;
  background-color: #fff;
  padding-bottom: 4rpx;
  position: relative;
}

.nav_option {
  display: inline-flex;
  line-height: 50px;
}

.nav_on {
  color: red;
  font-weight: bold;
}

.nav_line {
  position: absolute;
  height: 4rpx;
  left: 0;
  bottom: 0;
  transition: all .5s;
  display: flex;
  justify-content: center;
  transform: translateX(0)
}

.nav_line>view {
  width: 50%;
  height: 100%;
  background-color: red;
}

/*隐藏滚动条*/
::-webkit-scrollbar {
  width: 0;
  height: 0;
  color: transparent;
}

组件json

{
  "component": true,
  "usingComponents": {}
}

组件js

// component/slideNav/slideNav.js
Component({
  /**
   * 组件的属性列表
   */
  properties: {
    navList: {
      type: Array,
      value: '', //导航列表
    },

    fontSize: {
      type: Number,
      value: 28, //字体大小 单位rpx
    },

    padding: {
      type: Number,
      value: 20, //字体左右内边距 单位rpx
    },
  },

  /**
   * 组件的初始数据
   */
  data: {
    navLeft: 0,// 导航选项默认左偏移值
    subscript: 0,// 导航默认下标值
    lineLeft: 0,// 导航选中表示条左偏移值
  },

  lifetimes: {
    attached: function () {
      // 在组件实例进入页面节点树时执行
      this.res = wx.getSystemInfoSync();

      let { navList, fontSize, padding } = this.data;
      let pxScale = this.res.windowWidth / 750;/// 获取当前机型rpx转换px比例值
      let lineW = ((fontSize * pxScale) * navList[0].length) + (padding * pxScale) * 2;

      this.setData({ lineW });
	
	  // 返回当前导航选中下标 名称 左偏移值
      this.triggerEvent('tabFun', { subscript: 0, text: navList[0], navLeft: 0 });
    },
    detached: function () {
      // 在组件实例被从页面节点树移除时执行
    },
  },


  /**
   * 组件的方法列表
   */
  methods: {
    tabFun(e) {
      let { lineLeft, fontSize, padding } = this.data;
      let sysW = this.res.windowWidth / 2;/// 获取当前屏幕一半的值
      let pxScale = this.res.windowWidth / 750;/// 获取当前机型rpx转换px比例值
      let { offsetLeft } = e.target;// 获取当前选项左边界偏移的像素值
      let { text, subscript } = e.currentTarget.dataset;// 获取当前文字选项
      let textW = (fontSize * pxScale) * (text.length / 2);/// 获取当前选项文字一半宽度
      let aroundPadding = (padding * pxScale);/// 获取当前选项左右内边距一半的值
      let navLeft = offsetLeft - sysW + textW + aroundPadding;// 滚动条需要移动的距离
      let lineW = ((fontSize * pxScale) * text.length) + (aroundPadding * pxScale) * 2;// 选项提示线左偏移值
      
      navLeft = navLeft > 0 ? navLeft : 0;
      lineLeft = offsetLeft;

      this.setData({ navLeft, lineLeft, subscript, lineW });
		
	  // 返回当前导航选中下标 名称 左偏移值
      this.triggerEvent('tabFun', { subscript, text, navLeft });
    },
  }
})

相关标签: 微信小程序