├── .DS_Store ├── README.md ├── app.js ├── app.json ├── app.wxss ├── assets ├── home.png ├── home_active.png ├── mine.png └── mine_active.png ├── pages ├── .DS_Store └── app │ ├── .DS_Store │ ├── home │ ├── .DS_Store │ ├── home.js │ ├── home.json │ ├── home.wxml │ ├── home.wxss │ ├── hot │ │ ├── hot.js │ │ ├── hot.json │ │ ├── hot.wxml │ │ └── hot.wxss │ └── new │ │ ├── new.js │ │ ├── new.json │ │ ├── new.wxml │ │ └── new.wxss │ ├── mine │ ├── mine.js │ ├── mine.json │ ├── mine.wxml │ ├── mine.wxss │ ├── movie │ │ ├── movie.js │ │ ├── movie.json │ │ ├── movie.wxml │ │ └── movie.wxss │ └── music │ │ ├── music.js │ │ ├── music.json │ │ ├── music.wxml │ │ └── music.wxss │ ├── myapp.js │ ├── myapp.json │ ├── myapp.wxml │ └── myapp.wxss ├── project.config.json └── utils └── util.js /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cachecats/mini-multi-tab/661847bdfa77777d1ab5d1e0d0ca7f5ca3bd1129/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # mini-multi-tab 2 | 微信小程序自定义tab,多层tab嵌套实现 3 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | //app.js 2 | App({ 3 | onLaunch: function () { 4 | // 展示本地存储能力 5 | var logs = wx.getStorageSync('logs') || [] 6 | logs.unshift(Date.now()) 7 | wx.setStorageSync('logs', logs) 8 | 9 | // 登录 10 | wx.login({ 11 | success: res => { 12 | // 发送 res.code 到后台换取 openId, sessionKey, unionId 13 | } 14 | }) 15 | // 获取用户信息 16 | wx.getSetting({ 17 | success: res => { 18 | if (res.authSetting['scope.userInfo']) { 19 | // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 20 | wx.getUserInfo({ 21 | success: res => { 22 | // 可以将 res 发送给后台解码出 unionId 23 | this.globalData.userInfo = res.userInfo 24 | 25 | // 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回 26 | // 所以此处加入 callback 以防止这种情况 27 | if (this.userInfoReadyCallback) { 28 | this.userInfoReadyCallback(res) 29 | } 30 | } 31 | }) 32 | } 33 | } 34 | }) 35 | }, 36 | globalData: { 37 | userInfo: null 38 | } 39 | }) -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": [ 3 | "pages/app/myapp" 4 | ], 5 | "window": { 6 | "backgroundTextStyle": "light", 7 | "navigationBarBackgroundColor": "#fff", 8 | "navigationBarTitleText": "WeChat", 9 | "navigationBarTextStyle": "black" 10 | } 11 | } -------------------------------------------------------------------------------- /app.wxss: -------------------------------------------------------------------------------- 1 | /**app.wxss**/ 2 | .container { 3 | height: 100%; 4 | display: flex; 5 | flex-direction: column; 6 | align-items: center; 7 | justify-content: space-between; 8 | padding: 200rpx 0; 9 | box-sizing: border-box; 10 | } 11 | -------------------------------------------------------------------------------- /assets/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cachecats/mini-multi-tab/661847bdfa77777d1ab5d1e0d0ca7f5ca3bd1129/assets/home.png -------------------------------------------------------------------------------- /assets/home_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cachecats/mini-multi-tab/661847bdfa77777d1ab5d1e0d0ca7f5ca3bd1129/assets/home_active.png -------------------------------------------------------------------------------- /assets/mine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cachecats/mini-multi-tab/661847bdfa77777d1ab5d1e0d0ca7f5ca3bd1129/assets/mine.png -------------------------------------------------------------------------------- /assets/mine_active.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cachecats/mini-multi-tab/661847bdfa77777d1ab5d1e0d0ca7f5ca3bd1129/assets/mine_active.png -------------------------------------------------------------------------------- /pages/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cachecats/mini-multi-tab/661847bdfa77777d1ab5d1e0d0ca7f5ca3bd1129/pages/.DS_Store -------------------------------------------------------------------------------- /pages/app/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cachecats/mini-multi-tab/661847bdfa77777d1ab5d1e0d0ca7f5ca3bd1129/pages/app/.DS_Store -------------------------------------------------------------------------------- /pages/app/home/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cachecats/mini-multi-tab/661847bdfa77777d1ab5d1e0d0ca7f5ca3bd1129/pages/app/home/.DS_Store -------------------------------------------------------------------------------- /pages/app/home/home.js: -------------------------------------------------------------------------------- 1 | 2 | Component({ 3 | /** 4 | * 组件的属性列表 5 | */ 6 | properties: { 7 | 8 | }, 9 | 10 | /** 11 | * 组件的初始数据 12 | */ 13 | data: { 14 | currentTab: 0 15 | }, 16 | 17 | /** 18 | * 组件的方法列表 19 | */ 20 | methods: { 21 | switchTab(e) { 22 | console.log(e) 23 | let tab = e.currentTarget.id 24 | if (tab === 'tableft') { 25 | this.setData({ currentTab: 0 }) 26 | } else if (tab === 'tabright') { 27 | this.setData({ currentTab: 1 }) 28 | } 29 | } 30 | } 31 | }) 32 | -------------------------------------------------------------------------------- /pages/app/home/home.json: -------------------------------------------------------------------------------- 1 | { 2 | "component": true, 3 | "usingComponents": { 4 | "hot": "hot/hot", 5 | "new": "new/new" 6 | } 7 | } -------------------------------------------------------------------------------- /pages/app/home/home.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 最热 5 | 最新 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /pages/app/home/home.wxss: -------------------------------------------------------------------------------- 1 | 2 | .container{ 3 | display: flex; 4 | flex-direction: column; 5 | width: 100%; 6 | height: 100%; 7 | box-sizing: border-box; 8 | margin: 0; 9 | padding: 0; 10 | background: #fafafa 11 | } 12 | 13 | .tab-wrapper{ 14 | display: flex; 15 | flex-direction: row; 16 | width: 100%; 17 | height: 100rpx; 18 | background: #fff; 19 | } 20 | 21 | .tab-left, .tab-right{ 22 | flex: 1; 23 | font-size: 32rpx; 24 | color: #000; 25 | line-height: 100rpx; 26 | text-align: center; 27 | } 28 | 29 | .tab-active{ 30 | border-bottom: 2px solid #09bb07; 31 | } 32 | 33 | .content-wrapper{ 34 | width: 100%; 35 | flex: 1; 36 | } -------------------------------------------------------------------------------- /pages/app/home/hot/hot.js: -------------------------------------------------------------------------------- 1 | // pages/home/hot/hot.js 2 | Component({ 3 | /** 4 | * 组件的属性列表 5 | */ 6 | properties: { 7 | 8 | }, 9 | 10 | /** 11 | * 组件的初始数据 12 | */ 13 | data: { 14 | 15 | }, 16 | 17 | /** 18 | * 组件的方法列表 19 | */ 20 | methods: { 21 | 22 | } 23 | }) 24 | -------------------------------------------------------------------------------- /pages/app/home/hot/hot.json: -------------------------------------------------------------------------------- 1 | { 2 | "component": true, 3 | "usingComponents": {} 4 | } -------------------------------------------------------------------------------- /pages/app/home/hot/hot.wxml: -------------------------------------------------------------------------------- 1 | 我是最热页面 -------------------------------------------------------------------------------- /pages/app/home/hot/hot.wxss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/cachecats/mini-multi-tab/661847bdfa77777d1ab5d1e0d0ca7f5ca3bd1129/pages/app/home/hot/hot.wxss -------------------------------------------------------------------------------- /pages/app/home/new/new.js: -------------------------------------------------------------------------------- 1 | // pages/home/new/new.js 2 | Component({ 3 | /** 4 | * 组件的属性列表 5 | */ 6 | properties: { 7 | 8 | }, 9 | 10 | /** 11 | * 组件的初始数据 12 | */ 13 | data: { 14 | 15 | }, 16 | 17 | /** 18 | * 组件的方法列表 19 | */ 20 | methods: { 21 | 22 | } 23 | }) 24 | -------------------------------------------------------------------------------- /pages/app/home/new/new.json: -------------------------------------------------------------------------------- 1 | { 2 | "component": true, 3 | "usingComponents": {} 4 | } -------------------------------------------------------------------------------- /pages/app/home/new/new.wxml: -------------------------------------------------------------------------------- 1 | 我是最新页面 -------------------------------------------------------------------------------- /pages/app/home/new/new.wxss: -------------------------------------------------------------------------------- 1 | /* pages/home/new/new.wxss */ -------------------------------------------------------------------------------- /pages/app/mine/mine.js: -------------------------------------------------------------------------------- 1 | 2 | Component({ 3 | /** 4 | * 组件的属性列表 5 | */ 6 | properties: { 7 | 8 | }, 9 | 10 | /** 11 | * 组件的初始数据 12 | */ 13 | data: { 14 | currentTab: 0 15 | }, 16 | 17 | /** 18 | * 组件的方法列表 19 | */ 20 | methods: { 21 | switchTab(e) { 22 | console.log(e) 23 | let tab = e.currentTarget.id 24 | if (tab === 'tableft') { 25 | this.setData({ currentTab: 0 }) 26 | } else if (tab === 'tabright') { 27 | this.setData({ currentTab: 1 }) 28 | } 29 | } 30 | } 31 | }) 32 | -------------------------------------------------------------------------------- /pages/app/mine/mine.json: -------------------------------------------------------------------------------- 1 | { 2 | "component": true, 3 | "usingComponents": { 4 | "movie": "movie/movie", 5 | "music": "music/music" 6 | } 7 | } -------------------------------------------------------------------------------- /pages/app/mine/mine.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 电影 5 | 音乐 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /pages/app/mine/mine.wxss: -------------------------------------------------------------------------------- 1 | 2 | .container{ 3 | display: flex; 4 | flex-direction: column; 5 | width: 100%; 6 | height: 100%; 7 | box-sizing: border-box; 8 | margin: 0; 9 | padding: 0; 10 | background: #fafafa 11 | } 12 | 13 | .tab-wrapper{ 14 | display: flex; 15 | flex-direction: row; 16 | width: 100%; 17 | height: 100rpx; 18 | background: #fff; 19 | } 20 | 21 | .tab-left, .tab-right{ 22 | flex: 1; 23 | font-size: 32rpx; 24 | color: #000; 25 | line-height: 100rpx; 26 | text-align: center; 27 | } 28 | 29 | .tab-active{ 30 | border-bottom: 2px solid #09bb07; 31 | } 32 | 33 | .content-wrapper{ 34 | width: 100%; 35 | flex: 1; 36 | } -------------------------------------------------------------------------------- /pages/app/mine/movie/movie.js: -------------------------------------------------------------------------------- 1 | // pages/app/mine/movie/movie.js 2 | Component({ 3 | /** 4 | * 组件的属性列表 5 | */ 6 | properties: { 7 | 8 | }, 9 | 10 | /** 11 | * 组件的初始数据 12 | */ 13 | data: { 14 | 15 | }, 16 | 17 | /** 18 | * 组件的方法列表 19 | */ 20 | methods: { 21 | 22 | } 23 | }) 24 | -------------------------------------------------------------------------------- /pages/app/mine/movie/movie.json: -------------------------------------------------------------------------------- 1 | { 2 | "component": true, 3 | "usingComponents": {} 4 | } -------------------------------------------------------------------------------- /pages/app/mine/movie/movie.wxml: -------------------------------------------------------------------------------- 1 | 2 | 电影 3 | -------------------------------------------------------------------------------- /pages/app/mine/movie/movie.wxss: -------------------------------------------------------------------------------- 1 | /* pages/app/mine/movie/movie.wxss */ -------------------------------------------------------------------------------- /pages/app/mine/music/music.js: -------------------------------------------------------------------------------- 1 | // pages/app/mine/music/music.js 2 | Component({ 3 | /** 4 | * 组件的属性列表 5 | */ 6 | properties: { 7 | 8 | }, 9 | 10 | /** 11 | * 组件的初始数据 12 | */ 13 | data: { 14 | 15 | }, 16 | 17 | /** 18 | * 组件的方法列表 19 | */ 20 | methods: { 21 | 22 | } 23 | }) 24 | -------------------------------------------------------------------------------- /pages/app/mine/music/music.json: -------------------------------------------------------------------------------- 1 | { 2 | "component": true, 3 | "usingComponents": {} 4 | } -------------------------------------------------------------------------------- /pages/app/mine/music/music.wxml: -------------------------------------------------------------------------------- 1 | 2 | 音乐 3 | -------------------------------------------------------------------------------- /pages/app/mine/music/music.wxss: -------------------------------------------------------------------------------- 1 | /* pages/app/mine/music/music.wxss */ -------------------------------------------------------------------------------- /pages/app/myapp.js: -------------------------------------------------------------------------------- 1 | // pages/app/app.js 2 | Page({ 3 | 4 | /** 5 | * 页面的初始数据 6 | */ 7 | data: { 8 | currentTab: 0 9 | }, 10 | 11 | /** 12 | * 生命周期函数--监听页面加载 13 | */ 14 | onLoad: function (options) { 15 | 16 | }, 17 | 18 | /** 19 | * 生命周期函数--监听页面初次渲染完成 20 | */ 21 | onReady: function () { 22 | 23 | }, 24 | 25 | /** 26 | * 生命周期函数--监听页面显示 27 | */ 28 | onShow: function () { 29 | 30 | }, 31 | 32 | /** 33 | * 生命周期函数--监听页面隐藏 34 | */ 35 | onHide: function () { 36 | 37 | }, 38 | 39 | /** 40 | * 生命周期函数--监听页面卸载 41 | */ 42 | onUnload: function () { 43 | 44 | }, 45 | 46 | /** 47 | * 切换底部tab 48 | */ 49 | switchTab(e) { 50 | console.log(e) 51 | this.setData({ currentTab: e.currentTarget.dataset.current }); 52 | }, 53 | 54 | 55 | }) -------------------------------------------------------------------------------- /pages/app/myapp.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents":{ 3 | "home": "./home/home", 4 | "mine": "./mine/mine" 5 | } 6 | } -------------------------------------------------------------------------------- /pages/app/myapp.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 主页 17 | 18 | 19 | 20 | 21 | 我的 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /pages/app/myapp.wxss: -------------------------------------------------------------------------------- 1 | .container{ 2 | display: flex; 3 | flex-direction: column; 4 | width: 100%; 5 | height: 100%; 6 | box-sizing: border-box; 7 | margin: 0; 8 | padding: 0; 9 | background: #fafafa 10 | } 11 | 12 | .content { 13 | flex: 1; 14 | width: 100%; 15 | } 16 | 17 | .bottom-tab { 18 | background-color: #fff; 19 | flex: 1; 20 | display: flex; 21 | position: fixed; 22 | left: 0; 23 | bottom: 0; 24 | flex-direction: row; 25 | width: 100%; 26 | height: 120rpx; 27 | } 28 | 29 | .tab-item { 30 | display: flex; 31 | flex-direction: column; 32 | width: 50%; 33 | height: 100%; 34 | justify-content: center; 35 | align-items: center; 36 | border-top: 2rpx solid #a7a7a8; 37 | flex: 1; 38 | } 39 | 40 | .active { 41 | color: #13b5f5; 42 | 43 | } 44 | 45 | .item-text { 46 | font-size: 26rpx; 47 | } 48 | 49 | .item-img { 50 | width: 55rpx; 51 | height: 55rpx; 52 | } 53 | 54 | 55 | -------------------------------------------------------------------------------- /project.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "项目配置文件。", 3 | "packOptions": { 4 | "ignore": [] 5 | }, 6 | "setting": { 7 | "urlCheck": true, 8 | "es6": true, 9 | "postcss": true, 10 | "minified": true, 11 | "newFeature": true 12 | }, 13 | "compileType": "miniprogram", 14 | "libVersion": "2.0.8", 15 | "appid": "touristappid", 16 | "projectname": "project", 17 | "condition": { 18 | "search": { 19 | "current": -1, 20 | "list": [] 21 | }, 22 | "conversation": { 23 | "current": -1, 24 | "list": [] 25 | }, 26 | "game": { 27 | "currentL": -1, 28 | "list": [] 29 | }, 30 | "miniprogram": { 31 | "current": -1, 32 | "list": [] 33 | } 34 | } 35 | } -------------------------------------------------------------------------------- /utils/util.js: -------------------------------------------------------------------------------- 1 | const formatTime = date => { 2 | const year = date.getFullYear() 3 | const month = date.getMonth() + 1 4 | const day = date.getDate() 5 | const hour = date.getHours() 6 | const minute = date.getMinutes() 7 | const second = date.getSeconds() 8 | 9 | return [year, month, day].map(formatNumber).join('/') + ' ' + [hour, minute, second].map(formatNumber).join(':') 10 | } 11 | 12 | const formatNumber = n => { 13 | n = n.toString() 14 | return n[1] ? n : '0' + n 15 | } 16 | 17 | module.exports = { 18 | formatTime: formatTime 19 | } 20 | --------------------------------------------------------------------------------