微信小程序自定义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 相关文章推荐
Google AJAX 搜索 API实现代码
Nov 17 Javascript
javascript Array 数组常用方法
Apr 05 Javascript
JavaScript中的Promise使用详解
Jun 24 Javascript
跟我学习javascript的浮点数精度
Nov 16 Javascript
js document.getElementsByClassName的使用介绍与自定义函数
Nov 25 Javascript
深入理解vue.js双向绑定的实现原理
Dec 05 Javascript
基于javascript实现的购物商城商品倒计时实例
Dec 11 Javascript
微信小程序canvas写字板效果及实例
Jun 15 Javascript
微信JSAPI Ticket接口签名详解
Jun 28 Javascript
vue + element-ui的分页问题实现
Dec 17 Javascript
vue拖拽组件 vuedraggable API options实现盒子之间相互拖拽排序
Jul 08 Javascript
原生js实现自定义滚动条
Jan 20 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
全国FM电台频率大全 - 5 内蒙古自治区
2020/03/11 无线电
PHP数据库操作面向对象的优点
2006/10/09 PHP
php Sql Server连接失败问题及解决办法
2009/08/07 PHP
php生成静态页面的简单示例
2014/04/17 PHP
PHP中的socket_read和socket_recv区别详解
2015/02/09 PHP
PHP SOCKET编程详解
2015/05/22 PHP
thinkphp5.0整合phpsocketio完整攻略(绕坑)
2018/10/12 PHP
关于文本限制字数的js代码
2007/04/02 Javascript
js淡入淡出的图片轮播效果代码分享
2015/08/24 Javascript
在Javascript操作JSON对象,增加 删除 修改的简单实现
2016/06/02 Javascript
Nodejs从有门道无门菜鸟起飞必看教程
2016/07/20 NodeJs
判断横屏竖屏(三种)
2017/02/13 Javascript
原生node.js案例--前后台交互
2017/02/20 Javascript
Vuejs入门教程之Vue生命周期,数据,手动挂载,指令,过滤器
2017/04/19 Javascript
Javascript实现一个简单的输入关键字添加标签效果实例
2017/06/01 Javascript
JS设计模式之状态模式概念与用法分析
2018/02/05 Javascript
基于vue实现滚动条滚动到指定位置对应位置数字进行tween特效
2019/04/18 Javascript
js中switch语句的学习笔记
2020/03/25 Javascript
vue 实现超长文本截取,悬浮框提示
2020/07/29 Javascript
Javascript执行上下文顺序的深入讲解
2020/11/04 Javascript
JavaScript实现网页动态生成表格
2020/11/25 Javascript
ESLint 是如何检查 .vue 文件的
2020/11/30 Vue.js
[02:22:36]《加油!DOTA》总决赛
2014/09/19 DOTA
python处理文本文件并生成指定格式的文件
2014/07/31 Python
Python实现截屏的函数
2015/07/25 Python
Python表示矩阵的方法分析
2017/05/26 Python
python数据库操作mysql:pymysql、sqlalchemy常见用法详解
2020/03/30 Python
Python Selenium模块安装使用教程详解
2020/07/09 Python
毕业生在校学习的自我评价分享
2013/10/08 职场文书
小学生红领巾广播稿
2014/01/21 职场文书
放弃遗产继承公证书
2015/01/26 职场文书
设备技术员岗位职责
2015/04/11 职场文书
文艺晚会开场白
2015/05/29 职场文书
乱世佳人观后感
2015/06/08 职场文书
二十年同学聚会致辞
2015/07/28 职场文书
CSS 鼠标点击拖拽效果的实现代码
2022/12/24 HTML / CSS