微信小程序自定义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 相关文章推荐
jQuery 追加元素的方法如append、prepend、before
Jan 16 Javascript
js的alert样式如何更改如背景颜色
Jan 22 Javascript
JavaScript实现级联菜单的方法
Jun 29 Javascript
学习使用grunt来打包JavaScript和CSS程序的教程
Jan 04 Javascript
JavaScript中的原始值和复杂值
Jan 07 Javascript
Javascript删除指定元素节点的方法
Jun 21 Javascript
bootstrap flask登录页面编写实例
Nov 01 Javascript
微信小程序 详解下拉加载与上拉刷新实现方法
Jan 13 Javascript
React Native中Navigator的使用方法示例
Oct 13 Javascript
Swiper.js实现移动端元素左右滑动
Sep 08 Javascript
JQuery常用选择器功能与用法实例分析
Dec 23 jQuery
Nuxt 项目性能优化调研分析
Nov 07 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 array_intersect()函数使用代码
2009/01/14 PHP
PHP+jquery+ajax实现即时聊天功能实例
2014/12/23 PHP
PHP安装threads多线程扩展基础教程
2015/11/17 PHP
解析PHP之提取多维数组指定列的方法
2017/01/03 PHP
PHP jQuery+Ajax结合写批量删除功能
2017/05/19 PHP
PHP全局使用Laravel辅助函数dd
2019/12/26 PHP
PHP程序员简单的开展服务治理架构操作详解(三)
2020/05/14 PHP
50个优秀经典PHP算法大集合 附源码
2020/08/26 PHP
下载站控制介绍字数显示的脚本 显示全部 隐藏介绍等功能
2009/09/19 Javascript
基于jquery的一个图片hover的插件
2010/04/24 Javascript
js点击button按钮跳转到另一个新页面
2014/10/10 Javascript
jQuery+HTML5实现图片上传前预览效果
2015/08/20 Javascript
javascript闭包(Closure)用法实例简析
2015/11/30 Javascript
基于javascript制作微信聊天面板
2020/08/09 Javascript
JavaScript 数组- Array的方法总结(推荐)
2016/07/21 Javascript
JS版微信6.0分享接口用法分析
2016/10/13 Javascript
通过扫描二维码打开app的实现代码
2016/11/10 Javascript
JavaScript获取服务器时间的方法详解
2016/12/11 Javascript
利用require.js与angular搭建spa应用的方法实例
2017/07/19 Javascript
vue拦截器实现统一token,并兼容IE9验证功能
2018/04/26 Javascript
[55:48]VGJ.S vs TNC Supermajor 败者组 BO3 第二场 6.6
2018/06/07 DOTA
Python爬取三国演义的实现方法
2016/09/12 Python
详谈python http长连接客户端
2017/06/12 Python
Python+selenium 获取浏览器窗口坐标、句柄的方法
2018/10/14 Python
python 窃取摄像头照片的实现示例
2021/01/08 Python
HTML5 Canvas入门学习教程
2016/03/17 HTML / CSS
日本网路线上商品代购服务:转送JAPAN
2016/08/05 全球购物
俄罗斯在线购买飞机票、火车票、巴士票网站:Tutu.ru
2020/03/16 全球购物
Roxy俄罗斯官方网站:冲浪和滑雪板的一切
2020/06/20 全球购物
旅游管理专业生自荐信范文
2014/01/02 职场文书
档案接收函范文
2014/01/10 职场文书
保险经纪人求职信
2014/03/11 职场文书
小学社团活动总结
2014/06/27 职场文书
学校教师安全责任书
2014/07/23 职场文书
小学四年级学生评语
2014/12/26 职场文书
小学三年级语文教学反思
2016/03/03 职场文书