微信小程序自定义tab实现多层tab嵌套功能


Posted in Javascript onJune 15, 2018

小程序最近是越来越火了……

做小程序有一段时间了,总结一下项目中遇到的问题及解决办法吧。

项目中有个多 tab 嵌套的需求,进入程序主界面下面有两个 tab,进入A模块后,A模块最底下又有多个tab,每个tab上又嵌了2-4个不等的tab。。。

这种变态需求只能自定义tab了。

其实如果项目不是很复杂,没有多tab嵌套的需求,完全可以用小程序官方的 tabBar,方便快捷。
官方 tabBar 地址:https://developers.weixin.qq....

一、Demo结构

先看效果图吧

微信小程序自定义tab实现多层tab嵌套功能

微信小程序自定义tab实现多层tab嵌套功能

结构是这样的:程序主界面包含两个 tab:主页和我的,主页又包含两个tab:最热和最新;我的也包含两个tab:电影和音乐。

关系图如下:

项目
    主页
        最热
        最新
    我的
        电影
        音乐

二、开始撸代码

再看代码结构

微信小程序自定义tab实现多层tab嵌套功能

两种页面结构

小程序的页面分为两种:page 和 components。

page就是普通的页面, components是小程序为实现模块化而提供的自定义组件。

相同点:

都由四个文件:.js、.json、.wxml、.wxss、构成,.wxml、.wxss写法完全相同。

不同点:

components要在json文件中注明:"component": true

{
 "component": true,
 "usingComponents": {
  "movie": "movie/movie",
  "music": "music/music"
 }
}

js文件的结构和生命周期函数不同

下面是自动生成的page和components代码,可以感受下

page 的 js 代码

Page({
 /**
  * 页面的初始数据
  */
 data: {
 },
 /**
  * 生命周期函数--监听页面加载
  */
 onLoad: function (options) {
 },
 /**
  * 生命周期函数--监听页面初次渲染完成
  */
 onReady: function () {
 },
 /**
  * 生命周期函数--监听页面显示
  */
 onShow: function () {
 },
 /**
  * 生命周期函数--监听页面隐藏
  */
 onHide: function () {
 },
 /**
  * 生命周期函数--监听页面卸载
  */
 onUnload: function () {
 },
 /**
  * 页面相关事件处理函数--监听用户下拉动作
  */
 onPullDownRefresh: function () {
 },
 /**
  * 页面上拉触底事件的处理函数
  */
 onReachBottom: function () {
 },
 /**
  * 用户点击右上角分享
  */
 onShareAppMessage: function () {
 }
})
component 的 js 代码
Component({
 /**
  * 组件的属性列表
  */
 properties: {
 },
 /**
  * 组件的初始数据
  */
 data: {
 },
 /**
  * 组件的方法列表
  */
 methods: {
 }
})

本例中每个 tab 都是一个小程序中定义的 component , 只有最外层包裹的 myapp 是 page,因为page中只能嵌入component,component中也可以嵌入component。

代码解析

先看myapp,这是程序的主界面。它包含了两个tab:home 和 mine,分别对应页面下方的 主页 和 我的。

要引入自定义组件需要在 myapp.json文件中声明:

{
 "usingComponents":{
  "home": "./home/home",
  "mine": "./mine/mine"
 }
}

现在,就可以在 myapp.wxml 文件中愉快的引用了

<view class='container'>
 <view class='content'>
  <view wx:if='{{currentTab == 0}}'>
   <home/>
  </view>
  <view wx:if='{{currentTab == 1}}'>
   <mine/>
  </view>
 </view>
 <!-- 下面的两个tab -->
 <view class='bottom-tab'>
  <view class='tab-item {{currentTab == 0 ? "active" : ""}}' data-current="0" bindtap='switchTab'>
   <image src='{{currentTab == 0 ? "../../assets/home_active.png" : "../../assets/home.png"}}' class='item-img'></image>
   <text class='item-text'>主页</text>
  </view>

  <view class='tab-item {{currentTab == 1 ? "active" : ""}}' data-current="1" bindtap='switchTab'>
   <image src='{{currentTab == 1 ? "../../assets/mine_active.png" : "../../assets/mine.png"}}' class='item-img'></image>
   <text class='item-text'>我的</text>
  </view>
 </view>
</view>

tab切换的原理是根据 wx:if 或者 hidden 来控制视图的显示和隐藏,页面的data中设置一个变量currentTab来记录当前点击的是哪个tab,每次点击的时候更新currentTab的值。

切换tab的方法:

switchTab(e) {
  this.setData({ currentTab: e.currentTarget.dataset.current });
}

这里有几个需要注意的点:

这里判断相等用了 == 而不是 === ,因为通过 e.currentTarget.dataset.current取到的值是字符串类型的,也就是给 data 设置的值是字符串的0和1,如果用 === 就会判断出错。当然也可以强转成数字类型的,我比较懒~

控制组件显示隐藏可以用 wx:if 也可以用 hidden。两者是区别是如果用 wx:if ,每次切换tab的时候组件都会重新渲染,生命周期方法会重新调用执行。而用 hidden则不会重新渲染,生命周期函数也不会重新调用。

具体用哪个看业务需求了,贴一段官方的描述:

再看主页home,它本身是一个component,又包含了两个component :最热hot 和 最新new。

同样需要在home.json中注册这两个组件

{
 "component": true,
 "usingComponents": {
  "hot": "hot/hot",
  "new": "new/new"
 }
}

注意home本身是一个component,所以需要注明"component": true

布局文件 home.wxml

<view class='container'>
 <view class='tab-wrapper'>
  <view id='tableft' class='tab-left {{currentTab === 0 ? "tab-active":""}}' bindtap='switchTab'>最热</view>
  <view id='tabright' class='tab-right {{currentTab === 1 ? "tab-active" : ""}}' bindtap='switchTab'>最新</view>
 </view>
 <view class='content-wrapper' wx:if='{{currentTab === 0}}'><hot/></view>
 <view class='content-wrapper' wx:if='{{currentTab === 1}}'><new/></view>
</view>

js文件 home.js

Component({
 /**
  * 组件的属性列表
  */
 properties: {
 },
 /**
  * 组件的初始数据
  */
 data: {
  currentTab: 0
 },
 /**
  * 组件的方法列表
  */
 methods: {
  switchTab(e) {
   console.log(e)
   let tab = e.currentTarget.id
   if (tab === 'tableft') {
    this.setData({ currentTab: 0 })
   } else if (tab === 'tabright') {
    this.setData({ currentTab: 1 })
   }
  }
 }
})

给两个tab的view设置了id属性值为tableft和tabright,设置了id后就可以用e.currentTarget.id获取到当前点击的是哪个元素了。

其他几个页面的代码都大同小异,主要是判断当前点击的是哪个tab,然后根据currentTab判断该显示或隐藏哪个组件。

源码地址:

https://github.com/cachecats/...

总结

以上所述是小编给大家介绍的微信小程序自定义tab实现多层tab嵌套功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Javascript 相关文章推荐
在网页里看flash的trace数据的js类
Jan 10 Javascript
ajax异步刷新实现更新数据库
Dec 03 Javascript
简约JS日历控件 实例代码
Jul 12 Javascript
Javascript实现带关闭按钮的网页漂浮广告代码
Jan 12 Javascript
JavaScript获取当前页面上的指定对象示例代码
Feb 28 Javascript
在Node.js应用中使用Redis的方法简介
Jun 24 Javascript
Bootstrap源码解读下拉菜单(4)
Dec 23 Javascript
JavaScript编写一个贪吃蛇游戏
Mar 09 Javascript
详解Vue的computed(计算属性)使用实例之TodoList
Aug 07 Javascript
JS鼠标3次点击事件实现代码及扩展思路
Sep 12 Javascript
微信小程序 MinUI组件库系列之badge徽章组件示例
Aug 20 Javascript
vue实现页面滚动到底部刷新
Aug 16 Javascript
微信小程序实现自定义modal弹窗封装的方法
Jun 15 #Javascript
详解vue组件开发脚手架
Jun 15 #Javascript
在 vue-cli v3.0 中使用 SCSS/SASS的方法
Jun 14 #Javascript
vue cli 3.0 使用全过程解析
Jun 14 #Javascript
jQuery实现列表的增加和删除功能
Jun 14 #jQuery
vue采用EventBus实现跨组件通信及注意事项小结
Jun 14 #Javascript
JS对象与json字符串相互转换实现方法示例
Jun 14 #Javascript
You might like
php站内搜索并高亮显示关键字的实现代码
2011/12/29 PHP
有关于PHP中常见数据类型的汇总分享
2014/01/06 PHP
斜45度寻路实现函数
2009/08/20 Javascript
修改jQuery.Autocomplete插件 支持中文输入法 避免TAB、ENTER键失效、导致表单提交
2009/10/11 Javascript
javascript css styleFloat和cssFloat
2010/03/15 Javascript
非主流的textarea自增长实现js代码
2011/12/20 Javascript
原生js事件的添加和删除的封装
2014/07/01 Javascript
jQuery获取iframe的document对象的方法
2014/10/10 Javascript
js实现文本框宽度自适应文本宽度的方法
2015/08/13 Javascript
javascript数据类型验证方法
2015/12/31 Javascript
如何使用Bootstrap的modal组件自定义alert,confirm和modal对话框
2016/03/01 Javascript
浅谈js原生拖放
2016/11/21 Javascript
jQuery弹出div层过2秒自动消失
2016/11/29 Javascript
jQuery实现select模糊查询(反射机制)
2017/01/14 Javascript
浅谈React Native 中组件的生命周期
2017/09/08 Javascript
JS实现的邮箱提示补全效果示例
2018/01/30 Javascript
如何在微信小程序中实现Mixins方案
2019/06/20 Javascript
Vue vm.$attrs使用场景详解
2020/03/08 Javascript
微信小程序获取公众号文章列表及显示文章的示例代码
2020/03/10 Javascript
Python格式化css文件的方法
2015/03/10 Python
python使用BeautifulSoup分析网页信息的方法
2015/04/04 Python
Python和Perl绘制中国北京跑步地图的方法
2016/03/03 Python
Python学习小技巧之利用字典的默认行为
2017/05/20 Python
Python数据可视化:箱线图多种库画法
2019/11/06 Python
浅谈pandas.cut与pandas.qcut的使用方法及区别
2020/03/03 Python
深入理解Python 多线程
2020/06/16 Python
Django实现随机图形验证码的示例
2020/10/15 Python
Python获取指定网段正在使用的IP
2020/12/14 Python
HTML5单页面手势滑屏切换原理分析
2017/07/10 HTML / CSS
大四学生找工作的自荐信
2014/03/27 职场文书
欢迎家长标语
2014/10/08 职场文书
大一新生检讨书
2014/10/29 职场文书
不同意离婚答辩状
2015/05/22 职场文书
《神奇的鸟岛》教学反思
2016/02/22 职场文书
Vue + iView实现Excel上传功能的完整代码
2021/06/22 Vue.js
使用RedisTemplat实现简单的分布式锁
2021/11/20 Redis