第五章 “我要点爆”微信小程序云开发实例之从云端获取数据制作首页

下面我们来实现从云端获取数据,完成首页世界页面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/> 并不是一个组件,它仅仅是一个包装元素,不会在页面中做任何渲染,只接受控制属性。使用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',
    });
  },
})

运行效果图


至此,首页就制作完成了,可以说小程序的主体已经差不多了,云开发的便利我们也都尝试了。那么大家就快进行实践吧!

项目源码:https://github.com/xiedong2016/dbx

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容