WeChatアプレットでのプルダウンリフレッシュとプルアップロード

プルダウンリフレッシュとプルアップロードは、非常に一般的なビジネス要件です。WeChatアプレットでは、プルダウンリフレッシュメソッドが提供されていonPullDownRefreshます。プルアップローディングを実装することは比較的不便です。

プルダウンして更新

公式のWeChatドキュメントには多くの落とし穴がありますが、プルダウンリフレッシュの導入は依然として非常に包括的です。少しここに持ってきました。

  • まず、グローバルconfigwindowの構成enablePullDownRefresh
  • Page定義onPullDownRefreshフック関数。プルダウンリフレッシュ条件に達した後、フック関数が実行され、リクエストメソッドが開始されます。
  • リクエストが戻った後、wx.stopPullDownRefreshプルダウンの更新を停止するために呼び出します

設定

config = {
    pages: [
      'pages/index'
    ],
    window: {
      backgroundTextStyle: 'light',
      navigationBarBackgroundColor: '#ccc',
      navigationBarTitleText: 'WeChat',
      navigationBarTextStyle: '#000',
      enablePullDownRefresh: true
    }
  }复制代码

ページ

onPullDownRefresh() {
  wepy.showNavigationBarLoading() 
  setTimeout(()=>{
    this.getData = '数据拿到了'
    wepy.stopPullDownRefresh()
    wepy.hideNavigationBarLoading()
    this.$apply()
  },3000)
}复制代码

効果は次のとおりです。プルダウンプロセスが少し難しいことがわかります。これが実際に背景色が追加されない理由です。背景色を追加してから再試行してください。気分が良くなりました。プルダウンリフレッシュには、実装が簡単な既製の構成と方法がありますが、プルアップのロードは異なります。
画像

画像

ローディングを引き上げる

達成される効果を最初に見てください。これは3g側のプルアップローディングです。アプレットは同じ効果を達成する必要があります。まず第一に、機能は
画像

  • トップに戻るをクリックすると、これは非常によく実装されており、対応するトップに戻る機能があります
  • 画面をスライドして現在のページ番号を記録することも非常に簡単です。主に、スクロールイベントを監視し、対応するスクロールバーの高さを決定し、スクロールバーと子コンテナの高さを計算します。
  • 読み込みアニメーションをプルアップ

ここには2つの実装スキームがあります。1つは、page組み込みのプルダウンボトムフックイベントonReachBottomで、最後に時間の一部をプルダウンして、ボトムをヒットしたことを通知することですscroll-view。これは、イベントに付属のラベルです。次に、2つの方法を使用してプルアップロードを実装します。

ReachBottomでボトムイベントをプルアップ

テンプレート

<template>
  <view class="loading"></view>
  <view class="container"  
        @touchmove="moveFn" 
        @touchstart="startFn" 
        @touchend="endFn"
        style="transform:translate3d(0,{
   
   {childTop}}px,0)">
    <repeat for="{
   
   {list}}" 
            key="index" 
            index="index" 
            item="item">
        <view>{
   
   { item }}<text>{
   
   {index}}</text></view>
    </repeat>
    </view>
</template>复制代码

フック機能

data = {
  getData: '',
  top: 0,
  lastTop: 0,
  canDrag: false,
  list: []
}
onReachBottom() {
 this.canDrag = true
}
methods = {
  moveFn(ev) {
    let nowY = ev.changedTouches[0].clientY
    nowY = nowY-this.lastTop
    if(nowY > 0 )
      this.canDrag = false
    if( nowY<=0 && this.canDrag ) {
      this.top = nowY
    }
    if( -this.top>= this.maxTop  )
      this.top = -this.maxTop
  },
  startFn(ev) {
    this.lastTop = ev.changedTouches[0].clientY 
  },
  endFn() {
    if(this.top <= -this.maxTop) {
      this.text = "去请求数据了"
      setTimeout(()=>{
        this.text = "请求回来了"
        this.canDrag = false
        this.list.push(...["数据","数据","数据"])
        this.$apply()
        this.top = 0;
        return
      },1000)
    }
  },
  gotoTop() {
    wepy.pageScrollTo({
      scrollTop: 0
    })
  }
}复制代码

完了後の効果を見てみましょう。
画像

プルアップローディングを実現するためのローリングコンテナ

scroll-view:スクロール可能なビュー領域。
その特定の使用法は詳細には触れません。公式文書を見てください。上記の問題の解決策は次のとおりです。

  • bindscrolltolowerネイティブアナロジーグローバルフックonReachBottom
    テンプレート
<scroll-view    scroll-y 
                id="content"   
                @scroll="scroll"  
                @scrolltolower="lower" 
                scroll-top="{
   
   {gotoTopNum}}" 
                lower-threshold="100" 
                style="transform:translate3d(0,{
   
   {childTop}}px,0)">
    <view  class="sty-search" 
            @touchmove="moveContent" 
            @touchstart="startContent" 
            @touchend="endContent">...</view>
</scroll-view>复制代码

上記は最終的なテンプレートですが、なぜこれほど複雑なのか疑問に思われるかもしれません。複雑ですが、それぞれの属性は便利です。もちろん、私たちを待っているいくつかの落とし穴があります。
まず、ノードはローリングコンテナとサブコンテナに分割されます。

Q:スクロールコンテナにネストされたサブコンテナがあり、3つのドラッグメソッドがそれにバインドされているのはなぜですか?
A:scroll-viewコンテナはtouchmoveイベントをバインドできないため、これが最初のピットです。バインドするとどうなりますか?それほど多くはありませんが、イベントフックは呼び出されません。(このピットは公式ドキュメントにはありません。当時、バインドされていて呼び出されていませんでした。コミュニティで、touchmoveイベントをサブコンテナにバインドするという解決策が見つかりました)
コードを見てみましょう。

methods = {
    async lower() {
      this.canDrag = true
    },
    scroll (ev) {
      this.scrollTop = ev.detail.scrollTop
      if (ev.detail.deltaY > 0) {
        this.canDrag = false
      }
      let nowSet = this.documentHeight+this.scrollTop-this.contentHeader
      let num = Math.ceil(nowSet/this.listHeight) - 1
      num = Math.floor(num / this.pageBean.pageSize) + 1
      num = (num > this.pageBean.pageNo) ? this.pageBean.pageNo : num 
      if(num != this.page) {
        this.page = num
        this.$apply()
      }
    },
    startContent(ev) {
      this.lastTop = ev.changedTouches[0].clientY
      if(!this.documentHeight){
        this.documentHeight = wx.getSystemInfoSync().windowHeight
      }
      /* 这句是解决回到顶部的bug */
      if (this.gotoTopNum || this.gotoTopNum==0) { this.gotoTopNum = undefined }
    },
    moveContent (ev) {
      let {
        pageNo,
        pageSize,
        totalCount
      } = this.pageBean
      let nowY = ev.changedTouches[0].clientY
      nowY = nowY-this.lastTop
      if (this.canDrag && nowY) {
          this.state = 1;
          if (nowY <= -this.maxMove) {
            nowY = -this.maxMove
          }
          if (nowY <= 0) {
            this.childTop = nowY
          } 
      }
    },
    async endContent(ev) {
      let {
        pageNo,
        pageSize,
        totalCount
      } = this.pageBean
    
      if (this.childTop === -this.maxMove) {
        
        /* 状态 */
        if (pageNo >= this.maxPage || pageNo * pageSize >= totalCount) {
            this.state = 0
        } else {
          this.pageBean.pageNo++ 
          await this.fillData()
          this.childTop = 0
          this.canDrag = false
          this.$apply()
        }
      }
      /* 如果没超过刷新高度则重置 */
      this.childTop = 0
    },
    gotoTop() {
      this.gotoTopNum = 0
    },
}
复制代码

Q:なぜtouchStart時間をgotoTopNum設定する必要があるのundefinedですか?
A:このページの先頭に戻る機能があるため、先頭に戻るとgotoTopNum、実際にはscrollTop変更されますが、次のターンは0に設定されますが、0に設定されgotoTopNumます。もう一度上に戻ると、データが変更されていないため、ビューレイヤーは更新されません。したがって、無効な値がtouchStart指定されgotoTopNumた場合は、もう一度クリックして一番上に戻ると、ビューレイヤーも更新されます。

画像

ネイティブスクロールまたはスクロールビュー

比較 ネイティブスクロール スクロールビュー
パフォーマンス スムーズ ノードが多すぎると明らかにフリーズします
ローリング機能 onPageScroll bindscroll
トップに戻る wepy.pageScrollTo(object)にはデフォルトでアニメーション効果があり、キャンセルすることはできません ノードプロパティを設定する scroll-top
ピット まだ見つかりません 1、およびenablePullDownRefreshReachBottomは共存できません2、touchmoveイベント3をバインドできません、バーをダブルクリックしてトップの「イースターエッグ」に戻ることはできません

終了...あなたは...

どういたしまして。

実機試験

実装されたプルアップロードはエミュレータ上でスムーズに実行され、問題はありません。だが。
Macマシンの場合(当面はiphone5とiPhone7でテスト中)、プルアップまたはプルダウンのリバウンド効果などの問題があり、この効果はプルアップの距離に影響します。
この問題は古くから考えられてきましたが、今のところ上品に解決することはできません。
そこで、プロダクトマネージャーに要件を変更してもらい、プルアップアニメーション効果を削除して、最終的な効果が次のようになるようにしました。
画像

総括する

  1. バージョン1.4.0のリリース後、WeChatアプレットのノードの操作は高価であり、ブラウザーでの操作よりも高価です(これは、3g側のプルアップロード機能とWeChatアプレットの滑らかさを比較することで得られます)。多くのメソッドには、幅と高さをid取得するノード、またはノードセレクターを取得するノードなどの操作ノードが与えられます。これらのメソッドを呼び出す頻度を最小限に抑える函数节流)、結果をキャッシュしてください
  2. あなたがそれをする前にあなたの脳を使ってください!そうでなければ、あなたは多くの回り道をするでしょう...

 

おすすめ

転載: blog.csdn.net/weixin_44273311/article/details/106985027