做過 android 的都知道在 android 里面實(shí)現(xiàn) Tab切換 非常簡單,使用 android 提供的 TabLayout+ViewPager 很容器就實(shí)現(xiàn)了 Tab切換 的效果。 但是小程序中是沒有提供類似可以直接使用的組件,因此想要實(shí)現(xiàn)此功能需要我們自己去編碼實(shí)現(xiàn)。在上一篇文章中我提到的小程序練手項(xiàng)目就實(shí)現(xiàn)了 Tab切換 效果,具體效果圖可以參考文章微信小程序入門項(xiàng)目。 實(shí)現(xiàn)思路翻看小程序的文檔可以發(fā)現(xiàn),微信為我們提供了一個(gè) swiper 組件,通過該組件可以實(shí)現(xiàn) view 的滑動(dòng)切換,它的功能與 android 中的 ViewPager 是類似的。因此實(shí)現(xiàn) Tab切換 現(xiàn)在只需要實(shí)現(xiàn)頭部的 Tabbar 即可,對于該功能我們可以采用多個(gè)橫向排列的 view 組件構(gòu)成一個(gè) Tabbar ,每個(gè) view 組件作為一個(gè) Tab 項(xiàng),然后再將其點(diǎn)擊事件與 swiper 進(jìn)行關(guān)聯(lián)即可實(shí)現(xiàn) Tab的點(diǎn)擊和滑動(dòng)切換功能。而對于 Tabbar 的當(dāng)前 Tab 項(xiàng)下面的指示器我們可以采用 border-bottom 樣式實(shí)現(xiàn),也可以單獨(dú)使用一個(gè) view 組件作為指示器,我這里采用的是第二種方式實(shí)現(xiàn)指示器。 代碼實(shí)現(xiàn)代碼如下: 頁面布局代碼<viewclass="page"> <viewclass="navbar"> <blockwx:for="{{tabs}}"wx:key="*this"> <viewid="{{index}}"class="navbar__item {{activeIndex == index ? 'navbar__item_on' : ''}}"bindtap="navTabClick"> <viewclass="navbar__title">{{item.name}}</view> </view> </block> <viewclass="navbar__slider"style="width: {{sliderWidth}}px; transform: translateX({{sliderOffset}}px); -webkit-transform: translateX({{sliderOffset}}px);"></view> </view> <viewstyle="position: absolute;top: 68rpx;width: 100%;height:{{contentHeight}}px"> <swipercurrent="{{activeIndex}}"duration="300"bindchange="bindChange"> <swiper-item> <view>熱門視頻</view> </swiper-item> <swiper-item> <view>比賽集錦</view> </swiper-item> <swiper-item> <view>你懂專欄</view> </swiper-item> <swiper-item> <view>天下足球</view> </swiper-item> </swiper> </view> </view> 布局樣式代碼view , page { padding: 0px; margin: 0px; } .page { height: 100%; } .navbar { display: flex; position: absolute; z-index: 500; top: 0; width: 100%; } .navbar__item { position: relative; display: block; flex: 1; padding: 10rpx 0; text-align: center; font-size: 0; height: 48rpx; line-height: 48rpx; <!-- NavBar的總高度為:height + padding-top + padding-bottom = 68rpx --> } .navbar__item_on { color: #16B13A; } .navbar__slider { position: absolute; display: block; content: " "; left: 0; bottom: 0; height: 3px; background-color: #16B13A; transition: transform .3s; } .navbar__title{ display: inline-block; font-size: 15px; max-width: 8em; text-align: center; } swiper { height: 100%; } swiper-item{ width: 100%; padding-top: 20rpx; text-align: center; } js代碼var tabs = [ { name: "熱門視頻" }, { name: "比賽集錦" }, { name: "你懂專欄" }, { name: "天下足球" } ]; Page({ /** * 頁面的初始數(shù)據(jù) */ data: { tabs: tabs, //展示的數(shù)據(jù) slideOffset: 0,//指示器每次移動(dòng)的距離 activeIndex: 0,//當(dāng)前展示的Tab項(xiàng)索引 sliderWidth: 96,//指示器的寬度,計(jì)算得到 contentHeight: 0//頁面除去頭部Tabbar后,內(nèi)容區(qū)的總高度,計(jì)算得到 }, /** * 生命周期函數(shù)--監(jiān)聽頁面加載 */ onLoad: function(options){ var that = this; wx.getSystemInfo({ success: function(res){ that.setData({ //計(jì)算相關(guān)寬度 sliderWidth: res.windowWidth / that.data.tabs.length, sliderOffset: res.windowWidth / that.data.tabs.length * that.data.activeIndex, contentHeight: res.windowHeight - res.windowWidth / 750 * 68//計(jì)算內(nèi)容區(qū)高度,rpx -> px計(jì)算 }); } }); }, bindChange: function(e){ var current = e.detail.current; this.setData({ activeIndex: current, sliderOffset: this.data.sliderWidth * current }); console.log("bindChange:" + current); }, navTabClick: function(e){ this.setData({ sliderOffset: e.currentTarget.offsetLeft, activeIndex: e.currentTarget.id }); console.log("navTabClick:" + e.currentTarget.id); } }) 總結(jié)上面的布局代碼和js代碼其實(shí)寫起來都不難,關(guān)鍵在于css樣式的編寫,對于不熟悉CSS的人來說調(diào)樣式太痛苦了。這個(gè)效果也是我調(diào)了好半天,參考了好多代碼之后寫出來的,真o(╯□╰)o,看來想寫好小程序還得好好學(xué)學(xué)CSS樣式。 |
工作日 8:30-12:00 14:30-18:00
周六及部分節(jié)假日提供值班服務(wù)