第五章 “我要點爆”微信小程序雲開發實例之從雲端獲取數據制作首頁


下面我們來實現從雲端獲取數據,完成首頁世界頁面index的制作,首頁分為4個數據列表導航頁面,頁面具體內容如下:

推薦:為用戶推薦最新的點爆信息,它包含文本點爆內容和語音點爆內容。

文爆:篩選出文字點爆內容,只顯示文字點爆內容。

音爆:篩選出語音點爆內容,只顯示語音點爆內容。

爆榜:將點爆內容取出前20名進入排行。

【實現頁面內數據列表的滾動和導航切換后,每個導航下數據列表都在頂部】

由於我們使用的頭部導航欄是通過數據綁定在同一頁面進行切換,所以當一個頁面內數據列表向下滾動后,切換導航后頁面的scroolTop值已經改變,所以當從一個滾動過的導航數據列表切換到到另一個導航數據列表時,不能保持當前導航下數據列表在頂部,而會包含一個scroolTop值,下面我們就來實現導航切換后,數據列表為頂部位置。

在wxml中使用可滾動試圖區域scrool-view組件做為數據列表的容器,wxml中設置組件scroll-y="true"為y軸滾動,同時通過數據綁定scroll-top="{{scrollTop}}"設置豎向滾動條位置,設置組件絕對定位樣式。

<scroll-view scroll-y="true" scroll-top="{{scrollTop}}" style="position:absolute; top:0; left:0; right:0; bottom:0;">
</scroll-view>

在js中,我們給scrollTop設置初值為0,讓頁面打開時滾動條就在頂部

data: {
  scrollTop: 0,
}

在每一次導航切換時,都將scrollTop的值重新賦值為0,保證當前導航頁面滾動條在頂部。

this.setData({
  scrollTop: 0
})

【實現數據列表加載功能】

在組件中使用wx:for進行控制屬性綁定一個數組,使用數組中各項的數據重復渲染該組件。
wx:for-item制定數組當前元素變量名,將數據的id賦值給wx:key以便提高渲染效率,同時將數據的id賦值給id屬性,方便跳轉到詳情頁面。

block標簽,使用block標簽來進行條件渲染, 並不是一個組件,它僅僅是一個包裝元素,不會在頁面中做任何渲染,只接受控制屬性。使用block標簽來進行條件渲染是一個很好的選擇。

<view class="content_item"  wx:for="{{tarray}}" 
wx:for-item="recommend" wx:key="{{recommend._id}}" id="{{recommend._id}}">
  <block wx:if="{{recommend.text}}">
    <text>{{recommend.text}}</text>
  </block>
</view>

當然,我們也可以直接在組件中使用wx:if,例如在文爆中控制只顯示文本類爆文

<view class="content_item" bindtap="goopen" wx:for="{{tarray}}" 
wx:for-item="textbao" wx:key="{{textbao._id}}" id="{{textbao.detailId}}"
 wx:if="{{textbao.text}}">
</view>

在data中初始化一個數組tarray,用於保存從數據庫中獲取到的推薦爆文數據

data: {
  tarray: [],
}

orderBy指定按照時間逆序排序,limit指定查詢結果集數量上限為20,即最開始只從數據庫獲取20條數據,通過上拉加載來獲取更多的數據

// 推薦數據
  db.collection('bao').orderBy('time',     'desc').limit(20)
    .get();

上拉加載,設置一個lnum1變量來記錄當前頁面有多少條數據,每次上拉獲取10條數據,使用skip實現上拉加載更多,skip指定返回結果從指定序列后的結果開始返回

// 推薦數據
db.collection('bao').orderBy('wtime', 'desc').skip(lnum1).limit(10)
.get();

index.wxml完整代碼

<!--index.wxml-->
<view class="header">
  <label>
    <input type="text" bindtap="search"/>
  </label>
  <view class="navbar">
      <text class="item {{currentTab==index ? 'active' : ''}}" wx:for="{{navber}}" 
      data-index="{{index}}" wx:key="unique" bindtap="navbarTap">{{item}}</text>
  </view>
</view>
<scroll-view  class="content" scroll-y="true" scroll-top="{{scrollTop}}" 
bindscrolltolower="thebottom" style="position:absolute; top:0; left:0; right:0; bottom:0;">
<view class="content_box">
<!-- 推薦數據列表 -->
  <view class="recommend {{currentTab==0 ? 'show' : 'hide'}}">
    <view class="content_item" bindtap="goopen" wx:for="{{tarray}}" 
    wx:for-item="recommend" wx:key="{{recommend._id}}" id="{{recommend._id}}">
      <view class="citem_left">
        <image src="/images/tou1.png"></image>
      </view>
      <block wx:if="{{recommend.text}}">
        <view class="citem_mid">
          <text>{{recommend.text}}</text>
          <text>點爆方式:</text><text>{{recommend.wway}}</text>
        </view>
        <view class="citem_right">
          <image src="/images/re.png"></image>
          <text>{{recommend.temperature}}</text>
        </view>
      </block>
      <block wx:if="{{recommend.filename}}">
        <view class="citem_mid">
          <image src="/images/yuyin.png"></image>
          <text>點爆方式:</text><text>{{recommend.yway}}</text>
        </view>
        <view class="citem_right">
          <image src="/images/re.png"></image>
          <text>{{recommend.temperature}}</text>
        </view>
      </block>
    </view>
  </view>
  <!-- 文爆 -->
  <view class="textbao {{currentTab==1 ? 'show' : 'hide'}}">
    <view class="content_item" bindtap="goopen" wx:for="{{tarray}}" 
    wx:for-item="textbao" wx:key="{{textbao._id}}" id="{{textbao.detailId}}" wx:if="{{textbao.text}}">
      <view class="citem_left">
        <image src="/images/tou1.png"></image>
      </view>
      <view class="citem_mid">
        <text>{{textbao.text}}</text>
        <text>點爆方式:</text><text>{{textbao.wway}}</text>
      </view>
      <view class="citem_right">
        <image src="/images/re.png"></image>
        <text>{{textbao.temperature}}</text>
      </view>
    </view>
  </view>
  <!-- 音爆 -->
  <view class="voicebao {{currentTab==2 ? 'show' : 'hide'}}">
    <view class="content_item" bindtap="goopen" wx:for="{{tarray}}" 
    wx:for-item="voicebao" wx:key="{{voicebao._id}}" id="{{voicebao.detailId}}" wx:if="{{voicebao.filename}}">
      <view class="citem_left">
        <image src="/images/tou1.png"></image>
      </view>
      <view class="citem_mid">
        <image src="/images/yuyin.png"></image>
        <text>點爆方式:</text><text>{{voicebao.yway}}</text>
      </view>
      <view class="citem_right">
        <image src="/images/re.png"></image>
        <text>{{voicebao.temperature}}</text>
      </view>
    </view>
  </view>
  <!-- 爆榜 -->
  <view class="rankings {{currentTab==3 ? 'show' : 'hide'}}">
    <view class="content_item" bindtap="goopen" wx:for="{{barray}}" 
    wx:for-item="rankings" wx:key="{{rankings._id}}" id="{{rankings._id}}">
      <view class="number">
        {{index+1}}
      </view>
      <view class="citem_left">
        <image src="/images/tou1.png"></image>
      </view>
      <block wx:if="{{rankings.text}}">
        <view class="citem_mid">
          <text>{{rankings.text}}</text>
          <text>點爆方式:</text><text>{{rankings.wway}}</text>
        </view>
        <view class="citem_right">
          <image src="/images/re.png"></image>
          <text>{{rankings.temperature}}</text>
        </view>
      </block>
      <block wx:if="{{rankings.filename}}">
        <view class="citem_mid">
          <image src="/images/yuyin.png"></image>
          <text>點爆方式:</text><text>{{rankings.yway}}</text>
        </view>
        <view class="citem_right">
          <image src="/images/re.png"></image>
          <text>{{rankings.temperature}}</text>
        </view>
      </block>
    </view>
  </view>
</view>
</scroll-view>

index.js完整代碼

//index.js
//獲取應用實例
const app = getApp()
Page({
  data: {
    navber: ['推薦', '文爆', '音爆', '爆榜'],
    currentTab: 0,
    tarray: [],
    barray: [],
    lnum1: 20,//記錄當前已有數據數量
    stext: '',
    scrollTop: 0,
  },
  //上導航切換
  navbarTap: function (e) {
    this.setData({
      scrollTop: 0
    })
    this.setData({
      currentTab: e.currentTarget.dataset.index
    })
  },
  search: function (e) {
    wx.navigateTo({
      url: '../search/search'
    })
  },
  onLoad: function () {
    wx.showLoading({
      title: '加載中',
      mask: true
    })
    const db = wx.cloud.database()
    // 推薦數據
    db.collection('bao').orderBy('time', 'desc').limit(20)
      .get({
        success: res => {
          this.setData({
            tarray: res.data
          })
        }
      });
    // 排行數據
    db.collection('bao').orderBy('temperature', 'desc').limit(20)
      .get({
        success: res => {
          this.setData({
            barray: res.data
          })
        }
      });
    //模擬加載
    setTimeout(function () {
      wx.hideLoading()
    }, 1500);
  },
  goopen: function (e) {
    //獲取當前內容的標識id,保存,方便進入查詢
    var id = e.currentTarget.id
    wx.setStorageSync('id', id)
    wx.navigateTo({
      url: '../detail/detail',
    });
  },
  //下拉刷新
  onPullDownRefresh: function () {
    wx.showNavigationBarLoading() //在標題欄中顯示加載
    wx.showLoading({
      title: '加載中',
      mask: true
    })
    const db = wx.cloud.database()
    // 推薦數據
    db.collection('bao').orderBy('time', 'desc').limit(20)
      .get({
        success: res => {
          this.setData({
            tarray: res.data
          })
        }
      });
    // 排行數據
    db.collection('bao').orderBy('temperature', 'desc').limit(20)
      .get({
        success: res => {
          this.setData({
            barray: res.data
          })
        }
      });
    //模擬加載
    setTimeout(function () {
      // complete
      wx.hideNavigationBarLoading() //完成停止加載
      wx.stopPullDownRefresh() //停止下拉刷新
      wx.hideLoading()
    }, 1500);
  },
  //上拉加載
  thebottom: function () {
    var lnum1 = this.data.lnum1
    const db = wx.cloud.database()
    if (this.data.currentTab == 0) {
      // 顯示加載圖標
      wx.showLoading({
        title: '玩命加載中',
      })
      // 推薦數據
      db.collection('bao').orderBy('wtime', 'desc').skip(lnum1).limit(10)
        .get({
          success: res => {
            this.setData({
              tarray: this.data.tarray.concat(res.data),
              lnum1: lnum1 + 10
            })
            // 隱藏加載框
            wx.hideLoading()
          }
        });
    }
  }
})

運行效果圖:

搜索框搜索頁面的實現

app.json中加入search頁面路徑,編寫搜索頁面樣式

search.wxml

<view class="header">
  <label>
    <input type="text" bindconfirm="search" bindinput="content" 
    confirm-type="search" focus="true"/>
    <icon type="search" size="25" bindtap="search"/>
  </label>
</view>
<view class="content">
  <text class="nohave {{bol ? 'show' : 'hide'}}">你搜的什么吖,我莫得!</text>
  <view class="searchArray">
    <view class="content_item" bindtap="goopen" wx:for="{{tarray}}" 
    wx:for-item="searchArray" wx:key="{{searchArray._id}}" id="{{searchArray._id}}">
      <view class="citem_left">
        <image src="/images/tou1.png"></image>
      </view>
      <block wx:if="{{searchArray.text}}">
        <view class="citem_mid">
          <text>{{searchArray.text}}</text>
          <text>點爆方式:</text><text>{{searchArray.wway}}</text>
        </view>
        <view class="citem_right">
          <image src="/images/re.png"></image>
          <text>{{searchArray.temperature}}</text>
        </view>
      </block>
      <block wx:if="{{searchArray.filename}}">
        <view class="citem_mid">
          <image src="/images/yuyin.png"></image>
          <text>點爆方式:</text><text>{{searchArray.yway}}</text>
        </view>
        <view class="citem_right">
          <image src="/images/re.png"></image>
          <text>{{searchArray.temperature}}</text>
        </view>
      </block>
    </view>
  </view>
</view>

db.RegExp介紹:數據庫支持正則表達式查詢,開發者可以在查詢語句中使用 JavaScript 原生正則對象或使用 db.RegExp 方法來構造正則對象然后進行字符串匹配。在查詢條件中對一個字段進行正則匹配即要求該字段的值可以被給定的正則表達式匹配,注意正則表達式不可用於 db.command 內(如 db.command.in)。

使用db.RegExp方法構造正則對象然后進行字符串匹配,通過在對bao集合中text內容進行查詢時,給text賦值一個db.RegExp正則對象,這樣就實現了對text的模糊查詢。

db.collection('bao').where({
      //使用正則查詢,實現對搜索的模糊查詢
      text: db.RegExp({
        regexp: value,
        //從搜索欄中獲取的value作為規則進行匹配。
        options: 'im',
        //大小寫不區分
      })
    }).get()

search.js完整代碼

// pages/search/search.js
Page({
  data: {
    tarray: [],
    stext: '',
    bol: false,
  },
  search: function () {
    wx.showLoading({
      title: '玩命加載中',
    })
    this.setData({
      tarray: []
    })
    //連接數據庫
    const db = wx.cloud.database()
    var that = this
    var value = this.data.stext
    db.collection('bao').where({
      //使用正則查詢,實現對搜索的模糊查詢
      text: db.RegExp({
        regexp: value,
        //從搜索欄中獲取的value作為規則進行匹配。
        options: 'im',
        //大小寫不區分
      })
    }).get({
      success: res => {
        console.log(res)
        if (res.data.length == 0) {
          that.setData({
            bol: true
          })
        } else {
          that.setData({
            tarray: res.data
          })
        }
        wx.hideLoading()
      }
    })
  },
  content: function (e) {
    this.setData({
      stext: e.detail.value
    })
  },
  goopen: function (e) {
    //獲取當前內容的標識id,保存,方便進入查詢
    var id = e.currentTarget.id
    wx.setStorageSync('id', id)
    wx.navigateTo({
      url: '../detail/detail',
    });
  },
})

運行效果圖

至此,首頁就制作完成了,可以說小程序的主體已經差不多了,雲開發的便利我們也都嘗試了。那么大家就快進行實踐吧!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM