在最近的微信小程序開發(fā)中,遇到一個比較坑的界面開發(fā),說坑并不是因為它難,而是這其中包括了太多的開發(fā)時所要填的坑了,今天準(zhǔn)備將這些填完的小坑一個個刨出來仔細啃啃,做一個demo分享一下。

需求分析

簡單梳理一下需求:1.tabbar 需要用 fixed來跟隨 2.需要有上拉刷新,下拉加載的功能

需求很簡單,看起來一個個都不是很困難,但其中隱約的藏著許多個小坑洼,需要一個個仔細的來填上。首先先進個需求,position:fixed; 直接實現(xiàn),不存在任何困難。

實現(xiàn)方法

緊接著面對上拉刷新、下拉加載這個功能,老生常談,主要有兩個實現(xiàn)的方式:

1.scroll-view的上下監(jiān)聽函數(shù),在觸頂和觸底時分別執(zhí)行上拉刷新和下拉刷新機制。

2.微信api自帶的onReachBottom 和 onPullDownFresh 兩個函數(shù),分別為觸底執(zhí)行和下拉刷新。

先來介紹一下兩種方法:

1.利用scroll-view 來放置列表展示頁,將產(chǎn)品列表貼在scroll-view上,利用下滑屬性可以將產(chǎn)品展示在其中。在scroll-view觸底時, 綁定bindtaplower 這個函數(shù)將會被觸發(fā),達到“下拉刷新”的效果。

2.利用page標(biāo)簽自帶的onReachBottom 來達到下拉加載,上拉刷新。兩個api屬于自帶的api,而這個的上拉刷新也自帶了一個刷新動畫。

兩種方法均有其特點和優(yōu)異之處。從個人的開發(fā)喜好來說,在單列表中,第二種方式,即OnReachBottom 和 onPullDownFresh 的方式是優(yōu)于先進種方式的。為什么呢?因為它自帶了一個下拉刷新的動畫。而用scroll-view 的上拉刷新是不帶這個動畫的。所以誰更加先進不言而喻啦。

那么,我們應(yīng)該如何合適的使用這兩種方案?

微信小程序是一種很簡單的前端程序,但是它其中蘊含了許多的大大小小的坑。比如:在scroll-view 的碰邊函數(shù)上,會出現(xiàn)碰觸執(zhí)行多次的問題,即觸底執(zhí)行的判定過于多次,導(dǎo)致其瘋狂觸發(fā)函數(shù)。

面臨這樣的bug,我的先進想法是給他們上個鎖。每當(dāng)函數(shù)執(zhí)行時將鎖關(guān)上,在函數(shù)之行結(jié)束之時再將鎖打開。這樣就可以將函數(shù)重復(fù)執(zhí)行的問題解決了。

·上拉加載的函數(shù)·

upper: function() {
    var that = this
    var timestamp = Date.parse(new Date()) / 1000;
    var lastTime = this.data.lastLoadTime
    if (timestamp - lastTime < 5) {
        console.log('太快了')
    } else {
        that.setData({ lastLoadTime: timestamp })
        if (this.data.pullUpAllow) {
            console.log('刷新啦')
            that.setData({
                pullUpAllow: false
            })
            wx.showNavigationBarLoading() //在標(biāo)題欄中顯示加載
            console.log(that.data.classidnow)
            wx.request({
                url: '…',//這里放置的是接口的地址
                method: 'POST',
                data: {
                    shopid: getApp().globalData.shopid,
                    classid: that.data.classidnow,
                    userid: getApp().globalData.userid
                },
                header: {
                    'content-type': 'application/json' // 默認值
                },
                success: function(res) {
                    console.log(res)
                    if (res.data.data.length != 0) {
                        let shoppingDetail = res.data.data
                        that.setData({
                            shopping: shoppingDetail,
                            showNowData: false
                        })
                        console.log(that.data.shopping)
                    } else {
                        that.setData({
                            shopping: shoppingDetail,
                            showNowData: true
                        })
                    }
                },
                complete: function() {
                    wx.hideNavigationBarLoading() //完成停止加載
                    wx.stopPullDownRefresh() //停止下拉刷新
                    setInterval(() => {
                        that.setData({
                            pullUpAllow: true
                        })
                    }, 1000)
                }
            })
        }
    }
}

雖然可以解決下拉刷新觸發(fā)過多的問題,但因為上拉刷新的硬傷,所以我認為,在能使用onReachBottom的情況下,不要去使用scroll-view來寫。因為上拉加載時,用

Scroll-viewl動畫提示用戶在下拉刷新時,用的是showNavigationBarLoading()這個api,他做到的是在標(biāo)題上加入一個旋轉(zhuǎn)的小動畫。但是使用這個api時,會產(chǎn)生的一個問題就是,如果在上拉加載時不放手時,還是會瘋狂觸發(fā)上拉刷新的bug,這是后標(biāo)題會瘋狂鬼畜的抖動。這時候,我想到的解決方案是給上拉再次加入一個時間鎖。在三秒之內(nèi),再次觸發(fā)刷新時,禁止它的觸發(fā)。而自帶的onReachBottom 將不會再觸發(fā)這類問題,因為它要真真實實的上拉,所以綜上所述,如果能用onReachBottom ,辣就不要用scroll-view來寫上拉刷新啦,因為真的沒那么好用的。

如果你以為這就結(jié)束了?

上一段說了,如果如果能用onReachBottom ,就用這個,那么什么情況下不能用呢?這就關(guān)系到一開始說的需求了,需求上是關(guān)系到一個需要position:fixed的屬性的。那么,我們就要面臨一個問題了。如果用的是view 標(biāo)簽,在拉到1/2 時,做tab切換,時候就面臨一個問題:它的切換并不會切到頂部,而出現(xiàn)的也是在刷新之后的1/2處,這個體驗非常不人性化。那么,在面對需要置頂?shù)那闆r下,view的使用就會面臨一個瓶頸了。如何讓view置頂?這是個問題。

我的解決方案是:scroll-view 在每次切換時,讓scrollTop行內(nèi)標(biāo)簽歸零,這樣就可以讓每次切換置頂了。而因為scrolltop一開始就為0,先進次的上拉刷新是不會觸發(fā)的。在這樣的場景下,目前還是用scroll-view 來的更為簡便。