自定义小程序底部菜单
第一次写博客,如果有描述不当的地方,请多多包容,也欢迎指教。
做完第一个小程序的时候就觉得小程序的底部菜单有点坑,自己做的遮罩层根本无法遮住它,所以做第二个项目的时候,就决定自己模拟一个小程序底部菜单。下面说一下自己自定义底部菜单需要了解和注意的事项
1.小程序页面层级不能超过10级
2.小程序的wx.relaunch()可以清除所有页面痕迹并跳转至指定页面,但是,用户体验超级不好,跳转页面的时候会闪一下载跳转
3.小程序的wx.redirecto()关闭当前页面,跳转到应用内的某个页面,但是不允许跳转到 tabbar 页面。用户体验跟wx.relaunch()一样,让人看着就很不开心。
4.小程序的wx.navigateto()保留当前页面,跳转到应用内的某个页面,但是不能跳到 tabbar 页面。
5.小程序的wx.navigateBack可以通过delta返回至指定页面
综上所述,为了实现自定义的预想,又要解决用户体验问题。下面就是我的实现代码。
1.项目目录如上图
2.tabBar.wxml
1 <view class="wrapper"> 2 <view hidden='{{isModal}}' class='barModal'> 3 <view bindtap="hideToCreate" class='modal_bg'></view> 4 <view class='inte_ite'> 5 <view class="tobarItem" bindtap="toNewPost"> 6 <image class="toImgbar" src="../../icon/index_material.png" /> 7 <view>发帖子</view> 8 </view> 9 <view class="tobarItem" bindtap="toNewDynamic"> 10 <image class="toImgbar" src="../../icon/index_enterprise.png" /> 11 <view>发动态</view> 12 </view> 13 </view> 14 </view> 15 <view class="wrappe_tab"> 16 <view bindtap='tabBarFun' class='item_con' id="{{item.id}}" wx:for="{{tabBarList}}" wx:key="id"> 17 <image wx:if="{{!item.isCouter}}" class="{{item.class}}" src="{{item.iconPath}}" /> 18 <image wx:if="{{item.isCouter}}" class="{{item.class}}" src="{{item.selectedIconPath}}" /> 19 <view class="{{item.isCouter?'tab_font isCouter':'tab_font'}}">{{item.text}}</view> 20 </view> 21 </view> 22 </view>
3.tabBar.js
1 const app = getApp(); 2 Component({ 3 data: { 4 isModal: true, 5 tabBarList: [{ 6 pagePath: "pages/index/index", 7 text: "首页", 8 id: 1, 9 isCouter: true, 10 class: "tab_logo", 11 color: "#888888", 12 iconPath: "../../icon/indexIcon.png", 13 selectedColor: "#2873ff", 14 selectedIconPath: "../../icon/indexIconSe.png", 15 link: '../index/index' 16 }, 17 { 18 pagePath: "pages/mall/mall", 19 text: "商城", 20 class: "tab_logo", 21 id: 2, 22 isCouter: false, 23 iconPath: "../../icon/selectCarIcon.png", 24 selectedIconPath: "../../icon/selectCarIconSe.png", 25 link: '../mall/mall' 26 }, 27 { 28 pagePath: "pages/new/new", 29 class: "logo_mid", 30 id: 5, 31 isCouter: true, 32 iconPath: "../../icon/tabBar_new.png", 33 selectedIconPath: "../../icon/tabBar_new.png" 34 }, 35 { 36 pagePath: "pages/message/message", 37 text: "消息", 38 class: "tab_logo", 39 id: 3, 40 isCouter: false, 41 iconPath: "../../icon/consultingIcon.png", 42 selectedIconPath: "../../icon/consultingIconSe.png", 43 link: '../message/message' 44 }, 45 { 46 pagePath: "pages/mine/mine", 47 text: "我的", 48 id: 4, 49 isCouter: false, 50 class: "tab_logo", 51 color: "#888888", 52 selectedColor: "#2873ff", 53 iconPath: "../../icon/myIcon1.png", 54 selectedIconPath: "../../icon/myIconSe.png", 55 link: '../mine/mine' 56 } 57 ] 58 }, 59 ready: function(options) { 60 var ts = this; 61 // if (!app.pages){ 62 var pages = getCurrentPages(); 63 //} 64 65 var currentPage = pages[pages.length - 1]; //获取当前页面的对象 66 var url = currentPage.route; //当前页面url 67 var list = this.data.tabBarList; 68 console.log("pages"); 69 console.log(url); 70 if (url == "pages/index/index") { 71 list[0].isCouter = true; 72 list[1].isCouter = false; 73 list[4].isCouter = false; 74 list[3].isCouter = false; 75 this.setData({ 76 tabBarList: list, 77 }); 78 //debugger 79 } else if (url == "pages/mall/mall") { 80 list[1].isCouter = true; 81 list[0].isCouter = false; 82 list[4].isCouter = false; 83 list[3].isCouter = false; 84 this.setData({ 85 tabBarList: list, 86 }); 87 } else if (url == "pages/message/message") { 88 list[3].isCouter = true; 89 list[4].isCouter = false; 90 list[1].isCouter = false; 91 list[0].isCouter = false; 92 this.setData({ 93 tabBarList: list, 94 }); 95 } else if (url == "pages/mine/mine") { 96 list[4].isCouter = true; 97 list[0].isCouter = false; 98 list[1].isCouter = false; 99 list[3].isCouter = false; 100 this.setData({ 101 tabBarList: list, 102 }); 103 } 104 }, 105 methods: { 106 hideToCreate: function () { 107 this.setData({ 108 isModal: true, 109 }); 110 }, 111 toNewPost: function () { 112 wx.navigateTo({ 113 url: '../index/newPost/newPost' 114 }); 115 this.setData({ 116 isModal: true, 117 }); 118 }, 119 toNewDynamic: function () { 120 wx.navigateTo({ 121 url: "../index/newDynamic/newDynamic" 122 }); 123 this.setData({ 124 isModal: true, 125 }); 126 }, 127 tabBarFun: function(e) { 128 // console.log(e); 129 var ts = this; 130 var id = Number(e.currentTarget.id); 131 var list = this.data.tabBarList; 132 133 var pages = app.pages; 134 console.log('length:'+pages.length) 135 var currentPage = pages[pages.length - 1]; //获取当前页面的对象 136 137 var url = currentPage.route; //当前页面url 138 // console.log(url); 139 //console.log(id); 140 let len = 0, 141 flag = false; 142 // debugger 143 if (url != "pages/index/index" && id == 1) { 144 for (let i = 0; i < pages.length; i++) { 145 //// console.log(23); 146 ++len; 147 if (pages[i].route == "pages/index/index") { 148 149 flag = true; 150 break; 151 } 152 } 153 console.log('len:index'+len); 154 if (flag) { 155 wx.navigateBack({ 156 delta: pages.length - len 157 }); 158 159 } else { 160 wx.navigateTo({ 161 url: 'pages/index/index' 162 }); 163 } 164 } else if (url != "pages/mall/mall" && id == 2) { 165 for (let i = 0; i < pages.length; i++) { 166 //// console.log(23); 167 ++len; 168 if (pages[i].route == "pages/mall/mall") { 169 flag = true; 170 break; 171 } 172 } 173 console.log('len:mall' + len); 174 if (flag) { 175 wx.navigateBack({ 176 delta: pages.length - len 177 }); 178 } else { 179 wx.navigateTo({ 180 url: '/pages/mall/mall' 181 }); 182 } 183 } else if (url != "pages/message/message" && id == 3) { 184 for (let i = 0; i < pages.length; i++) { 185 console.log(23); 186 ++len; 187 if (pages[i].route == "pages/message/message") { 188 flag = true; 189 break; 190 } 191 } 192 console.log('len:msg' + len); 193 if (flag) { 194 wx.navigateBack({ 195 delta: pages.length - len 196 }); 197 198 } else { 199 wx.navigateTo({ 200 url: '/pages/message/message' 201 }); 202 } 203 204 } else if (url != "pages/mine/mine" && id == 4) { 205 for (let i = 0; i < pages.length; i++) { 206 ++len; 207 if (pages[i].route == "pages/mine/mine") { 208 console.log(23); 209 flag = true; 210 break; 211 } 212 } 213 console.log('len:mine' + len); 214 if (flag) { 215 wx.navigateBack({ 216 delta: pages.length - len 217 }); 218 } else { 219 wx.navigateTo({ 220 url: '/pages/mine/mine' 221 }); 222 } 223 224 } else if (id == 5) { 225 this.setData({ 226 isModal: !this.data.isModal, 227 }) 228 } 229 } 230 } 231 })
4.tabBar.json
1 { "component": true }
5.tabBar.wxss
1 .wrapper{ 2 height: 100rpx; 3 } 4 .item_con { 5 width: 20%; 6 float: left; 7 text-align: center; 8 height: 100rpx; 9 color: #444; 10 } 11 12 .modal_bg { 13 background-color: rgba(100, 100, 100, 0.6); 14 position: fixed; 15 width: 100%; 16 height: 100%; 17 } 18 19 .barModal { 20 background-color: rgba(100, 100, 100, 0.6); 21 position: fixed; 22 width: 100%; 23 height: 100%; 24 left: 0; 25 z-index: 1; 26 top: 0; 27 } 28 29 .inte_ite { 30 position: absolute; 31 bottom: 100rpx; 32 left: 0; 33 width: 100%; 34 } 35 36 .toImgbar { 37 width: 80rpx; 38 height: 80rpx; 39 } 40 41 .inte_ite { 42 background-color: #fff; 43 padding: 10rpx; 44 } 45 46 .tobarItem { 47 width: 50%; 48 font-size: 28rpx; 49 float: left; 50 text-align: center; 51 } 52 53 .wrappe_tab { 54 position: fixed; 55 left: 0; 56 z-index: 2; 57 height: 100rpx; 58 width: 100%; 59 border-top: 1rpx solid #eee; 60 bottom: 0; 61 background-color: #fff; 62 } 63 64 .tab_logo { 65 width: 45rpx; 66 height: 38rpx; 67 margin-top: 15rpx; 68 } 69 70 .tab_font { 71 font-size: 28rpx; 72 position: relative; 73 top: -4rpx; 74 } 75 76 .logo_mid { 77 width: 85rpx; 78 height: 65rpx; 79 margin-top: 17rpx; 80 } 81 82 .isCouter { 83 color: #2873ff; 84 }
6.在需要用到的页面文件中使用,如
//index.js
1 onShow(){ app.pages = getCurrentPages(); }
//index.json
1 { 2 "usingComponents": { 3 "tabBar": "../../component/tabBar/tabBar" 4 } 5 }
//index.wxml
1 <tabBar></tabBar>