第五章:如何開發一款內容展現類小程序(下)

做者:知曉雲 - 小程序開發快人一步css

前面咱們搭建了一個簡單的頁面框架,實現了文章列表展現和跳轉文章詳情的功能。然而,僅有這些功能是明顯不夠的,所以,接下來,我將向你講解,如何加上更多稍顯複雜,但頗有必要的功能,包括加載更多文章列表,顯示未讀與已讀狀態和文章分享。數據庫

加載更多文章列表

前面,咱們在首頁模擬了獲取第一頁文章的請求。考慮到性能問題,大部分狀況下咱們不會在首頁展現出全部的文章列表,在 PC 上咱們能夠經過分頁來實現,而在移動端,比較常見的作法是在列表末尾經過上拉或者一個加載更多按鈕,來獲取更多文章。這裏,咱們將採用第二種作法。編程

加載更多的邏輯是這樣的:當一次請求獲取到的文章數量大於或等於咱們規定的每頁數量時,按鈕的文案會顯示爲 」加載更多「,而且點擊後會去獲取下一頁的文章,而若是獲取到的文章數量小於咱們規定的每頁數量時,按鈕的文案會顯示爲 」已無更多「。小程序

這裏須要解釋一下,若是獲取到最後一頁的文章數剛好爲咱們規定的每頁數量時,當點擊加載更多,會繼續獲取下一頁文章,此時獲取到的文章數量爲 0 ,小於規定的每頁數量,按鈕的文案變爲 」已無更多「。數組

爲了簡化步驟,咱們模擬的下一頁的文章數量小於 4 篇,這樣,當咱們點擊一次加載更多後,按鈕文章會變爲 」已無更多「。緩存

這裏咱們須要增長兩個變量,一個是 isEnd,用於標識已無更多,另外一個是 isLoading,用於防止用戶連續屢次點擊加載更多按鈕。bash

經過小程序中的按鈕組件的 loading 屬性,能夠方便地顯示正在加載中的樣式。app

// pages/index/index.wxml
<button type="default" plain="{{true}}" loading="{{loading}}" bindtap="loadMore">
  {{loadMoreText}}
</button>
複製代碼

製造靜態數據,數量爲 2 條,表示已無更多。框架

// pages/index/index.js
const lastPage = [{
  id: '5',
  title: '超新約全書',
  description: '一個以折磨人爲樂趣的上帝',
  cover: 'https://xxx.xxx.xxx.jpg'
}, {
  id: '6',
  title: '2001太空漫遊 2001',
  description: '現代科幻電影技術的里程碑',
  cover: 'https://xxx.xxx.xxx.jpg'
}]
 
// pages/index/index.js
let isEnd = false
Page({
  data: {
    articles: [],
    loading: false,
    loadMoreText: '加載更多'
  },
 
  onLoad: function() {
    this.getArticles(true)
  },
 
  loadMore: function(event) {
    this.getArticles()
  }
})
複製代碼

從新實現 getArticles 方法:異步

getArticles: function(isFirstPage) {
  if (!isEnd && !this.data.loading) {
    this.setData({ loading: true })
    setTimeout(() => {
      if (isFirstPage) { 
        this.setData({
          articles: firstPage,
          loading: false
        })
      } else {
        this.setData({
          articles: firstPage.concat(lastPage),
          loading: false
        })
        if (lastPage.length < pageLimit) {
          isEnd = true
          this.setData({ loadMoreText: '已無更多' })
        }
      }
    }, 1000)
  }
}
複製代碼

每一次獲取到新的頁面時,咱們經過 Array.concat 方法,將它拼接入到以前的文章列表後面,而後進行 setData 。這樣,咱們就實現了加載更多文章列表的功能了。

顯示未讀與已讀狀態

有時候,咱們也會忘了本身曾閱讀過某篇文章,雖然對於大多數人來講這並不常見,但對於我這種記憶力不是很好的人來講,這事情發生的頻率仍是很大的。因此,我有必要爲本身提高一下用戶體驗。

當用戶在首頁點擊了某個文章列表項後,咱們須要將該列表項的文字顏色設置爲灰色,正常狀況下,他們是黑色的。

爲了標記用戶是否讀過某篇文章,咱們在用戶點擊某篇文章的同時,將其文章 id 保存起來。相似這種數據,咱們通常不會保存到數據庫,由於有點牛刀小試了,咱們只須要將數據保存到本地便可,只要用戶不清緩存數據就不會丟失,即便請了緩存,丟失了數據,也並不會形成多大的損失。

接下來,讓咱們看看如何在小程序中使用本地存儲吧。

本地存儲的使用及同異步接口的差別

小程序提供了兩種方法讓咱們操做本地存儲,包括同步操做與異步操做。

同步:

添加:wx.setStorageSync

獲取:wx.getStorageSync

異步:

添加:wx.setStorage

獲取:wx.getStorage

關於同步和異步的區別,有個例子很好地作了說明:

同步調用就是你喊你的朋友吃飯,你朋友在忙,你就一直在那等,等你朋友忙完了,大家一塊兒去。

異步調用就是你喊你的朋友吃飯,你朋友說知道了,待會忙完去找你,你就去作別的事了。

可見,異步調用的效率會比同步好,但應用到編程語言上,就要稍微多寫點代碼了。以獲取 key 爲 id 的數據爲例,咱們講解一下這兩種調用方式分別是如何使用的:

同步:

var value = wx.getStorageSync('key')
console.log('id', value)
複製代碼

異步:

wx.getStorage({
  key: 'id',
  success: function(res) {
    console.log('id', res.data)
  } 
})
複製代碼

能夠看到,使用同步操做相對於異步操做更簡單也更簡潔一點,異步操做主要是用在對性能有要求的場景,這裏爲了操做方便,咱們將使用同步操做來實現該功能。

功能實現

在前面的基礎上,咱們在每一個 article 數據中再加入一個 isReaded 字段,用於標識該文章是否已被閱讀。

當用戶在首頁點擊某一篇文章時,要先判斷 storage 中是否有 key 爲 READED_ARTICLES (字符串常量)的記錄,若是沒有,則建立該記錄,其 value 爲數組,並將該文章的 id push 到該數組中。若是已存在名爲 READED_ARTICLES 的記錄,則判斷該文章的 id 是否包含在其 value (數組類型)中,不存在則 push ,存在則跳過。

// pages/index/index.js
toDetailPage: function(e) {
  let id = e.currentTarget.dataset.id
  let readedArticles = wx.getStorageSync(READED_ARTICLES)
 
  if (!readedArticles) {
    wx.setStorageSync(READED_ARTICLES, [id])
  } else if(readedArticles.indexOf(id) == -1) {
    readedArticles.push(id)
    wx.setStorageSync(READED_ARTICLES, readedArticles)
  }
  this.setData({articles: this.addReadStatus(this.data.articles)})
  wx.navigateTo({
    url: `../detail/index?id=${id}`
  })
}
複製代碼

上面,咱們在 setData 的時候再也不使用 this.data.articles,而是使用 this.addReadStatus(this.data.articles),addReadStatus 是咱們本身定義的方法,它接受一個 articles 參數,並根據 localStorage 中保存的,已閱讀過的文章的 id ,來給文章添加 isReaded 屬性。

addReadStatus: function(articles) {
  let readedArticles = wx.getStorageSync(READED_ARTICLES)
  if (!readedArticles) {
    return articles
  }
  
  let newArticles = []
  for (let i = 0; i < articles.length; i++) {
    let article = Object.assign(articles[i])
    if (readedArticles.indexOf(article.id) != -1) {
      article.isReaded = true
    } else {
      article.isReaded = false
    }
    newArticles.push(movie)
  }
    
  return newArticles
}
複製代碼

同時,咱們不要忘了另外一種狀況,當用戶從新打開小程序的時候,咱們也須要給文章加上 isReader 屬性。即在 getArticles 方法中的 setData 裏使用 addReadStatus,以下:

// pages/index/index.js
this.setData({
  articles: oldArticles.concat(this.addReadStatus(data)),
  loading: false
})
複製代碼

有了 isReader 作標誌,咱們就不難爲不一樣狀態的文章加上不一樣的樣式了。

// pages/index/index.wxml
<button type="default" plain="{{true}}" loading="{{loading}}" bindtap="loadMore">
  {{loadMoreText}}
</button>
複製代碼

到這裏,咱們就完成了一個有點複雜,但又很實用的小功能了。接下讓咱們再開發一個能夠提升咱們應用活躍度的功能——分享。

文章分享

分享基本上是每一個應用都必不可少的功能,在小程序中實現一個常規的分享功能,是再簡單不過了,但簡單也意味着不夠特別,若是你想要得到更多的分享量,那就須要在分享方式上下點功夫了。

接下來我將介紹兩種方式來實現分享功能,一種是最常規的也是最普通的,點擊右上角的菜單,使用彈出的菜單項中分享菜單項。 另外一種方法是自定義一個分享按鈕,用戶點擊按鈕後即彈出確認分享框,該方法靈活性強,而且比第一種少操做了一步。好了,讓咱們開始吧。

不管使用菜單仍是自定義控件來實現分享功能,都須要咱們在要加入分享功能的 Page 中實現 onShareAppMessage(options) 方法,在該方法中設置該頁面的轉發信息和轉發成功或失敗的回調。

Page({
  onShareAppMessage: function (options) {
    return {
      title: '標題',
      path: '/page/user?id=123',
      success: function() {
        // 轉發成功
        console.log(`share by: ${options.from}`)
      },
      fail: function() {
        // 轉發失敗
      }
    }
  }
})
複製代碼

options 參數說明:

1. 使用菜單中的分享功能

使用菜單中的分享功能,咱們只需在 page 中定義 onShareAppMessage 便可。

// pages/detail/index.js onShareAppMessage: function (options) { return { title: this.data.article.title, imageUrl: this.data.article.poster, path: pages/detail/index?id=${id}, } }

2. 自定義分享組件

與使用菜單中的分享功能同樣,咱們一樣要實現 onShareAppMessage 方法。自定義分享組件,咱們須要藉助到 button 組件的 open-type 屬性,將其設置爲 "share" ,當點擊按鈕便會彈出分享確認框。

<button open-type="share">分享<button/>
複製代碼

到這裏不少人會有疑惑了,難道咱們必須使用 button 組件才能實現自定義分享組件嗎?button 組件那麼醜……。很遺憾,咱們的確須要使用 button 組件,但也不用那麼失望,雖然咱們要使用 button 組件,但誰說 button 組件就醜了呢,咱們還有 css 的嘛。如今,咱們就藉助 css ,實現一個懸浮於屏幕右下角,圓形的,帶背景圖片的分享按鈕。

<button plain="{{true}}" open-type="share" />
// pages/detail/index.wxss
.article-share-btn {
  position: fixed;
  right: 30rpx;
  bottom: 30rpx;
  width: 70rpx;
  height: 70rpx;
  background-image: url("https://cloud-minapp-1131.cloud.ifanrusercontent.com/1eNFg1HrAVjWkrNQ.png");
  background-size: 70rpx 70rpx;
  border: 0 !important;
}
複製代碼

最後的效果以下:

到這裏,咱們就搭建起了一個文章展現小程序基本的頁面框架,同時爲其加上了一些很實用的小功能,你也能夠閱讀小程序官方文檔,找找那些你感興趣的功能的小程序 API ,來豐富你的小程序功能吧。

相關閱讀

第一章:一文了解小程序

第二章:手把手,動手編寫一個簡單小程序(上)

第三章:手把手,動手編寫一個簡單小程序(下)

第四章:如何開發一款內容展現類小程序(上)

相關文章
相關標籤/搜索