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

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

1. 項目簡介

這一章節,我將一步一步教你們如何搭建一個文章展現小程序,從最開始使用靜態數據,逐漸添加加載更多數據、分享、記錄閱讀信息等功能,一點點解答開發一個內容展現類小程序所需的基本功能的實現方法。java

2. 搭建簡單的頁面

這裏,咱們先從最簡單的搭建頁面框架開始。數據庫

首先,咱們先理清咱們所須要的頁面。咱們這裏只須要用到一個文章列表展現頁,和一個文章詳情頁。在列表頁選擇一篇文章,點擊便進入詳情頁。json

理清了咱們須要的頁面後,在項目的 pages 文件夾中建立相應的頁面,而且在 app.json 文件中進行聲明。小程序

// app.json
{
  "pages": [
    "pages/index/index",
    "pages/detail/index"
  ],
}
複製代碼

文章列表

列表循環

咱們須要在文章列表展現頁將咱們文章的簡要信息,以列表的形式展現出來。這裏主要會用到小程序的 wx:for 屬性。在小程序組件上使用 wx:for 屬性綁定一個數組,便可使用數組中各項的數據對該組件進行重複渲染,配合 wx:for 一塊兒用的屬性以下:數組

wx:for: 指定須要遍歷的數組性能優化

wx:for-item:遍歷數組時,指定當前項的別名bash

wx:for-index:當前遍歷到數組的第幾個服務器

wx:key:主要用於性能優化併發

除了 wx:for 屬性,其它並不是必需要使用的。咱們經過一個例子,來看看它是如何使用的:

<view wx:for="{{array}}" wx:for-index="idx" wx:for-item="itemName">
  {{idx}}: {{itemName.message}}
</view>
複製代碼

頁面生命週期

通常狀況下,咱們都會從服務器獲取文章列表數據,這就涉及到了在頁面的哪一個生命週期去獲取數據。

一個頁面的生命週期以下表所示:

咱們能夠經過一個簡單的試驗來了解這些生命週期的觸發時機。

首先新建三個頁面 index 頁面,test 頁面和 another 頁面。在 index 頁面添加一個 navigator 組件,url 指向 test 頁面;在 test 頁面添加一個 navigator 組件,url 指向 another 頁面,同時在其 js 文件中,添加如下代碼:

Page({
  onLoad: function (options) {
    console.log('onLoad')  
  },
 
  onReady: function () {
    console.log('onReady')
  },
 
  onShow: function () {
    console.log('onShow')
  },
 
  onHide: function () {
    console.log('onHide')
  },
 
  onUnload: function () {
    console.log('onUnload')
  },
})
複製代碼

當點擊 index 頁面的 navigator 組件時,跳轉到 test 頁面,此時會依次觸發 onLoad, onShow, onReady 方法,再點擊 test 頁面上的 navigator 組件時,跳轉到 another 頁面,則會觸發 onHide 方法;點擊返回,頁面回到 test 頁面,此時會觸發 onShow 方法;再次點擊返回,回到 index 頁面,則會觸發 onUnload 方法。

瞭解了不一樣生命週期的觸發時機後,咱們就能夠很好地選擇一個適合的時機發起咱們的數據請求了。若是你只想在頁面載入的時候拉取一次數據,你能夠選擇 onLoad;若是你的數據會在其它頁面被改到,你須要更頻繁地更新數據,你能夠選 onShow;若是你想在頁面渲染完成後加載獲取數據,那就選擇 onReady。後面拉取文章列表信息,我是選擇在 onLoad 的時候加載的。

功能實現

爲了更清晰地講解如何開發文章列表展現功能,咱們會使用一些靜態數據來替代真實的數據庫數據。

這裏先定義第一頁的數據,爲了方便,咱們規定一頁就只有四條數據。

// pages/index/index.js
const firstPage = [{
  id: '1',
  title: '裝修祕訣',
  description: '文藝氣息爆棚的精緻白色現代家',
  cover: 'http://xxx.xxx/xxx.jpg', 
},
 ...
{
  id: '4',
  title: '咖啡指南',
  description: '咖啡製做終極指南',
  cover: 'http://xxx.xxx/xxx.jpg', 
}]
複製代碼

咱們在 data 中加入 articles 屬性,用於存放獲取到的文章列表數據,而且在 onLoad 方法中調用獲取數據的方法,經過使用 setTimeout 來模擬請求數據的效果。

// pages/index/index.js
Page({
  data: {
    articles: [],
  },
  onLoad: function() {
    this.getArticles()
  },
  getArticles: function() {
    setTimeout(() => {
      this.setData({
        articles: firstPage,
      })
    }, 1000)
  },
複製代碼

編寫好 javascript 邏輯,獲取到咱們須要的數據後,咱們就能夠在 wxml 裏將數據賦給 wx:for ,渲染文章列表。

// pages/index/index.wxml
<view wx:for="{{articles}}" wx:for-item="article" wx:key="id">
  <image  src="{{article.cover}}" data-id="{{article.id}}" />
  <view>
     <view data-id="{{article.id}}">{{article.title}}</view>
    <view>{{article.description}}</view>
  </view>
</view>
複製代碼

上面除了 wx:for 屬性,其它並不是必須的,能夠按照咱們的須要使用。這裏咱們重點講一下 wx:key。

當咱們作列表渲染時,若是不提供 wx:key 的話,控制檯會拋出以下警告:

Now you can provide attr "wx:key" for a "wx:for" to improve performance.
複製代碼

警告並不是錯誤,所以不修改也是不要緊的,可是,咱們最好了解一下爲何小程序想要咱們添加 wx:key 屬性,瞭解了這個,咱們就能夠更好地決定是否須要加上這個屬性了。

咱們來看看,小程序官方文檔是如何解釋的:

使用 wx:key 能夠指定列表中項目的惟一的標識,若是列表中項目的位置動態改變或者有新的項目添加到列表中,原來的列表中的項目能夠保持本身的特徵和狀態(如 < input/ > 中的輸入內容, 的選中狀態)不變,即他們能夠只進行從新排序而不是從新建立。

能夠看出,wx:key 實際上是起到性能優化的做用,當咱們的列表數據發生變化時,相應的視圖也會發生變化,從而致使 DOM 的從新建立或從新排序,很明顯,從新排序比從新建立性能要好,所以咱們要避免沒必要要的從新建立。

假設咱們對數組 [A, B, C, D] 進行列表渲染, 如今要在 B 和 C 之間加入 F,若是不使用 wx:key 的話,進行 diff 後,發現排在第一和第二位的 A 和 B 沒有發生改變,而第三爲和第四位從 C 和 D 分別變爲了 F 和 C,所以這裏須要建立的節點就包括 F ,C,D。

再來看看加了 wx:key 的狀況,儘管 C 和 D 的位置都向下挪了一位,但他們的 key 是沒有發生變化的,所以斷定爲從新排序而不是從新建立。

關於列表渲染,還有一個小技巧想要和各位分享一下,那就是使用 組件。前面咱們將 wx:for 放在了 view 組件上,以下:

<view wx:for="{{[1, 2, 3]}}">
  <view> {{index}}: </view>
  <view> {{item}} </view>
</view>
複製代碼

這裏渲染出來的每一個列表項都將會被 所包含,但有時候,咱們就是須要渲染一個包含多節點的結構塊,這是 組件就派上用場了, 並不會真實的被渲染出來:

<block wx:for="{{[1, 2, 3]}}">
  <view> {{index}}: </view>
  <view> {{item}} </view>
</block>
複製代碼

關於列表渲染,我就講這麼多了,更多細節能夠參考小程序開發文檔,框架-視圖層-WXML-列表渲染這一小節。接下來咱們講一講如何實現跳轉到文章詳情頁。

添加跳轉文章詳情頁功能

僅僅有文章列表還不夠,咱們還須要容許用戶選擇某篇文章,點擊進入到它的詳情頁面。前面咱們已經定義好了頁面,如今只須要在點擊封面和點擊文章標題的時候,作下路由跳轉,跳到詳情頁便可。

實現路由跳轉的兩種方式

在小程序中,你可使用如下兩種方式實現路由跳轉。

  1. 在 wxml 代碼中添加跳轉邏輯

經過使用 navigator 組件,並配上相應的屬性,便可實現路由跳轉。這種實現方式的優勢是,邏輯清晰,經過瀏覽 wxml 便可瞭解到頁面的調整邏輯,缺點是靈活性差。

<navigator url="{{pageUrl}}" open-type="navigator">跳轉</navigator>
複製代碼

navigator 組件支持如下幾個重要屬性:

其中,open-type 的有效值包括:

navigate:保留當前頁面,跳轉到應用內的某個頁面

redirect:關閉當前頁面,跳轉到應用內的某個頁面

switchTab:跳轉到 tabBar 頁面,並關閉其餘全部非 tabBar 頁面

navigateBack:關閉當前頁面,返回上一頁面或多級頁面

reLaunch:關閉全部頁面,打開到應用內的某個頁面

更多屬性細節,可查看小程序文檔,組件-導航 這一小節。

  1. 用 javascript 代碼中添加跳轉邏輯

小程序也支持使用 API 來實現路由跳轉,包括 wx.navigateTo, wx.redirectTo, wx.switchTab, wx.navigateBack, wx.reLaunch, 與 navigate 組件的 open-type 屬性相對應。

這種實現方法的有點事靈活性強,大部分狀況下,咱們作路由調整的同時,還須要作其它的動做,用 javascript 代碼來控制路由跳轉將很容易作到這一點,所以,咱們將採用這種方法來實現跳轉文章詳情頁功能。

在 JavaScript 中實現路由跳轉

咱們想要的效果是,點擊文章封面和點擊文章標題的時候,會跳轉到文章詳情頁,因此咱們須要給這兩個節點綁上相應的事件。同時,爲了告知點擊的具體文章,咱們要在這兩個節點上加上 data-id="{{article.id}}" 屬性。

// pages/index/index.wxml
<image src="{{article.cover}}" data-id="{{article.id}}" bindtap="toDetailPage" />
  <view class="article-item__desc> <view data-id="{{article.id}}" bindtap="toDetailPage">{{article.title}}</view> <view>{{article.description}}</view> </view> </view> 複製代碼

而後實現 toDetailPage 事件的邏輯:

// pages/index/index.js
toDetailPage: function(e) {
  let id = e.currentTarget.dataset.id
  wx.navigateTo({
    url: `../detail/index?id=${id}`
  })
}
複製代碼

跳轉的功能已經實現了,如今須要解決的是,如何在詳情頁顯示相應文章的詳情。

在詳情頁面,咱們須要知道到底哪篇文章須要被顯示,前面,咱們在跳轉連接上加了 id=${id} 參數,所以,咱們只須要在 onLoad 方法中獲取到這個參數,併發送獲取相應文章詳情的請求便可。一樣,咱們使用靜態數據,並模擬一下獲取文章詳情的請求。

// pages/detail/index.js
const articleInfo = {
  title: '特斯拉卡車發佈',
  category: '科技',
  poster: 'https://xxx.xxx/xxx.jpg',
  content: '特斯拉卡車發佈',
  created_at: '2017-11-11'
}
 
Page({
  data: {
    article: {},
  },
 
  onLoad: function(option) {
    this.getArticle(option.id)
  },
 
  getArticle: function(id) {
    this.setData({article: articleInfo})
  },
})
<view>{{article.title}}</view>
<view>{{article.created_at}}</view>
<view>{{article.content}}</view>
複製代碼

相關閱讀

第一章:一文了解小程序

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

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

相關文章
相關標籤/搜索