邊做邊學(xué)入門微信小程序之仿豆瓣評分

微信小程序由于適用性強、邏輯簡要、開發(fā)迅速的特性,疊加具有海量活躍用戶的騰訊公司背景,逐漸成為了輕量級單一功能應(yīng)用場景的較佳承載方式,諸如電影購票、外賣點餐、移動商城、生活服務(wù)等場景服務(wù)提供商迅速切入了。

為了貼合實際的應(yīng)用情況,本篇以豆瓣評分小程序為參考樣例,邊做邊學(xué)小程序的入門開發(fā)知識。

目錄

效果圖
Demo源碼
開發(fā)環(huán)境
了解官方樣例
    開發(fā)者工具
    樣例源碼結(jié)構(gòu)
開發(fā)實戰(zhàn)
    底部Tab卡頁
    分析開發(fā)需求
    評分條模板
        rpx長度單位
        數(shù)據(jù)綁定
        條件渲染
        列表渲染
    電影海報模板
        模板的使用
    區(qū)塊模板
    主頁
        網(wǎng)絡(luò)請求
        邏輯實現(xiàn)
        setData
        點擊事件
    詳情頁
    更多頁
擴展知識
思考題

效果圖

先看一下對比效果圖,共三個頁面,分別為首頁、更多頁和詳情頁,左側(cè)為豆瓣評分官方小程序,右側(cè)為仿作。因API數(shù)據(jù)問題,沒有做搜索功能。

主頁

img

更多頁

img

詳情頁

img

Demo源碼

本篇完整源碼已提交在: https://github.com/cnwen/wechatapp_movie

開發(fā)環(huán)境

調(diào)試基礎(chǔ)庫:1.9.91(2018.03.07)

微信開發(fā)者工具:Windows版v1.02.1802270

了解官方樣例

打開微信開發(fā)者工具,新建一個小程序項目。

1.選擇項目代碼存放的目錄;

2.填入你的小程序AppID(若無AppID請點擊“注冊”獲取,也可選擇“體驗小程序”,如需真機預(yù)覽須有AppID);

3.勾選“建立普通快速啟動模板”。

點擊“確定”按鈕后,開發(fā)者工具將為我們建立一個簡單的小程序模板,我們可以通過這個樣例來建立對開發(fā)者工具和小程序的初步認識。

img

開發(fā)者工具

我們觀察開發(fā)者工具,發(fā)現(xiàn)由三個主要區(qū)域構(gòu)成,分別是模擬器、編輯器和調(diào)試器。

img

模擬器:頂端含有三個下拉列表,可以配置模擬的機型和所處的網(wǎng)絡(luò)環(huán)境。

編輯器:分為源碼目錄區(qū)域和代碼區(qū)域。

調(diào)試器:頂端含有控制臺、網(wǎng)絡(luò)、存儲等選項卡頁。

樣例源碼結(jié)構(gòu)

根目錄含有pages、utils文件夾和三個名稱為app的文件。顧名思義,pages正是存放小程序各個頁面的文件夾,一些公共的工具類建議放在utils文件夾,app文件是小程序的全局文件。

點擊查看app.json文件的源碼,可以看到含有pages和window兩個鍵值對。

img

pages負責(zé)配置小程序的頁面,里面有2條路徑,分別對應(yīng)index和logs頁面。

Tips:1.第一條路徑固定為小程序的首頁,如果把logs路徑放到首位,那么logs頁面是首頁;2.同一個頁面的js/wxml/wxss文件的名稱必須相同,因為路徑是以文件名稱來識別的,路徑是“pages/index/index”,注意后面不帶js/wxml/wxss等后綴,系統(tǒng)會在該路徑尋找需要格式文件;3.需要顯示的獨立頁面都需要在此處配置,template模板文件則不需要。

window負責(zé)全局的窗口配置,如導(dǎo)航欄背景色、導(dǎo)航欄文字等。你可以修改它們的值,保存后在模擬器上看到效果。

試試將navigationBarBackgroundColor的值改為#ffae00,將navigationBarTitleText的值改為“電影排行榜”,按Ctrl+S鍵保存看看模擬器中的效果吧。

Tips:1.backgroundTextStyle的值目前只有兩種:light和dark;2.navigationBarTextStyle的值目前只有兩種:black和white。

回到源碼目錄,對比index和logs頁面的構(gòu)成,發(fā)現(xiàn)index頁面并沒有.json文件,可見這個文件并非是必須的。但是,如果有這個文件,那么必然不能為空,否則控制臺會報錯,可在里面寫入一個大括號{}保存即可。

開發(fā)實戰(zhàn)

官方樣例先認識到這里,我們對開發(fā)者工具和小程序源碼構(gòu)成有了一個初步的印象后,開始邊做邊學(xué)。

底部Tab卡頁

我們使用鼠標右鍵將源碼目錄pages下的index/logs兩個文件夾刪除,并打開app.json,在pages的值中配置下圖中的兩條路徑。

img

按Ctrl+S鍵保存,開發(fā)者工具將自動在指定路徑為我們創(chuàng)建兩個頁面,如下圖所示。

img

此時,模擬器中的首頁已經(jīng)變成了movies目錄下的index頁面,因為我們剛才把這個頁面的路徑配置在app.json文件中pages值的首位了。

img

如果我們要查看mine頁面怎么辦呢?除了使用后文將提到的頁面跳轉(zhuǎn)功能,這里用Tab卡頁的切換功能來試試。在app.json文件中添加tabBar內(nèi)容,如下所示。

{
  "pages":[
    "pages/movies/index",
    "pages/mine/mine"
  ],
  "window":{
    "backgroundTextStyle":"light",
    "navigationBarBackgroundColor": "#ffae00",
    "navigationBarTitleText": "電影排行榜",
    "navigationBarTextStyle":"white"
  },
  "tabBar": {
    "list": [
      {
        "pagePath": "pages/movies/index",
        "text": "電影"
      },
      {
        "pagePath": "pages/mine/mine",
        "text": "我的"
      }
    ],
    "borderStyle": "black",
    "selectedColor": "#ffae00"
  }
}

模擬器預(yù)覽效果如下圖:

img

在list的值中,我們配置了2個卡頁,text是卡頁的文字,pathPath代表了頁面路徑,當(dāng)點擊卡頁時,將跳轉(zhuǎn)到指定路徑的頁面。注意卡頁數(shù)必須為2-5個才合規(guī),否則控制臺會報錯。并且,這里的路徑必須被包含在頂端的pages值中,因為所有可抵達頁面都必須在pages中配置路徑。

紅色箭頭指向處有一條水平灰色線,這是卡頁和內(nèi)容頁的分界線,由borderStyle屬性控制,其值默認為black,目前暫時只有black和white值可選。

selectedColor表示卡頁選中時,其文字的顏色,用十六進制表示。另外卡頁背景色也可配置。

選項卡可以含有圖標,配置方法如下:

{
    "pagePath": "pages/movies/index",
    "text": "電影",
    "iconPath": "images/tabbar/movie.png",
    "selectedIconPath": "images/tabbar/movieSelected.png"
}

img
img

一個為默認圖標,一個是選中時顯示的圖標。(請看圖標路徑,我在左側(cè)目錄樹的根目錄新建了images/tabbar目錄,并放入了4張圖標,圖標資源在Github源碼中有)

這樣,首頁Tab便完成了。接下來我們來分析頁面結(jié)構(gòu),并實現(xiàn)一些公用的template模板文件。

分析開發(fā)需求

作為編碼者,在開始編碼之前,我們要養(yǎng)成先從整體層面上分析整體需求的好習(xí)慣,有利于后續(xù)的代碼編寫及維護。

img

觀察首頁、更多頁和電影詳情頁,可以很容易地歸納出一些可以共用的頁面元素:1.首頁由三大塊組成,正在熱映、即將上映和排行榜區(qū)塊除了數(shù)據(jù)不同,頁面結(jié)構(gòu)是相同的(即紅色框,后文我用block區(qū)塊模板代指這塊);2.每個block模板中含有若干個海報模板,由電影海報、電影名稱和評分條、評分數(shù)組成(藍色框,后文稱poster海報模板);3.每個評分條是由5顆星星組成的(粉紅框,后文稱ratingbar評分條模板)。

評分條模板

模板頁面(template)是官方提供的一種實現(xiàn)頁面元素復(fù)用、減少重復(fù)工作的良好實現(xiàn)形式。

從上面的分析中,我們發(fā)現(xiàn)這里提到的三個模板是層層嵌套的,因此,作為入門學(xué)習(xí)者,我們先從最內(nèi)層的模板開始實現(xiàn),即先實現(xiàn)評分條ratingbar模板文件。

img

評分星星有三種狀態(tài),我們在images目錄中新建ratingbar目錄,并將這三個星星圖標放入。(Github源碼中含有本文所需的所有素材)

img

在movies目錄右鍵鼠標,依次新建名為ratingbar的目錄和Page。打開app.json文件,我們發(fā)現(xiàn)開發(fā)者工具自動在pages值為我們配置了ratingbar頁面的路徑。

img

作為模板文件,是在其它頁面中導(dǎo)入使用的,它不會單獨被使用,因此其實它不需要在app.json的pages值中配置路徑,并且該頁面只需wxml和wxss即可,js和json文件都是用不上的,它所含的頁面元素的數(shù)據(jù)和行為都是由引用它的頁面來操縱的,后文會對此有所涉及。

但在此時,我們需要在模擬器中調(diào)試、查看其效果,所以要將它當(dāng)作單獨頁面來使用一次,調(diào)試完后可將js/json文件刪除,并刪除在app.json中pages值中的路徑,此是后話,暫且略過。

我們在app.json中將ratingbar頁面路徑移到pages值的首位(見上圖),保存后發(fā)現(xiàn)模擬器的首頁變成了ratingbar頁面。

img

頁面上唯一的一條內(nèi)容是由開發(fā)者工具在新建頁面時自動生成的。我們打開ratingbar.wxml頁面,將自動生成的標簽內(nèi)容刪除,并輸入以下內(nèi)容,按Shift+Alt+F鍵格式化代碼:

<!--pages/movies/ratingbar/ratingbar.wxml-->
<view class='ratingbar-stars'>
  <!--全黃星星-->
  <image src='/images/ratingbar/star_fill_whole.png'/>
  <image src='/images/ratingbar/star_fill_whole.png'/>
  <image src='../../../images/ratingbar/star_fill_whole.png'/>
  <!--半黃半灰星星-->
  <image src='/images/ratingbar/star_fill_half.png'/> 
  <!--全灰星星-->
  <image src='../../../images/ratingbar/star_fill_none.png'/>
</view> 

可以視為官方提供的一種容器,需要成對出現(xiàn)的,在這里它內(nèi)部含有5個image組件。class表示其樣式,它將會去同頁面的wxss文件中查找并渲染值為.ratingbar-stars的樣式(見下文)。image是圖像組件,有一個屬性src,表示要顯示的圖片的地址。像這類內(nèi)容不需要再包含其它控件的控件,你也可以寫成單閉合標簽的形式。

這里src的路徑出現(xiàn)了2種寫法,絕對路徑和相對路徑,如果不了解的可另外拓展一下,這里的路徑是一樣的。

再點開ratingbar.wxss文件,并輸入以下內(nèi)容:

/* pages/movies/ratingbar/ratingbar.wxss */
/* class="ratingbar-stars"的控件的樣式 */
.ratingbar-stars {
  display: flex;
  flex-direction: row;
  padding-right: 4rpx;
}

/* class="ratingbar-stars"的控件下所包含的image控件的樣式 */
.ratingbar-stars image {
  height: 17rpx;
  width: 17rpx;
  padding-top: 5rpx;
  padding-right: 4rpx;
}

這里的首個.ratingbar-stars樣式(請注意樣式名前面有個小點號“.”),與的class相呼應(yīng),將會用于渲染該控件。

這里采用了CSS中著名的flex彈性盒子模型,flex-direction:row;意味著其內(nèi)部控件將采用水平橫向的方式排列,要表示豎直排列可將值改為column。

第二個.ratingbar-stars image樣式(請注意中間有空格,且image前面沒有點號),表示渲染class='ratingbar-stars'的控件內(nèi)部包含的image控件,這里表示了高height、寬width、距離頂部的內(nèi)邊距padding-top、距離右側(cè)的內(nèi)邊距padding-right。CSS的更多屬性知識歡迎另行拓展,這是一個多記多練才能生巧的知識。

rpx長度單位

rpx是微信小程序推出的單位,可以根據(jù)不同手機不同的屏幕寬度進行內(nèi)容自適應(yīng),使頁面元素在不同屏幕寬度的手機上看起來具有一致性。

無論手機屏幕實際寬度是多少,小程序都會在底層將屏幕寬度換算成750份,如果設(shè)計師以iphone6的750*1334(物理像素)為標準出設(shè)計稿的話,1rpx=0.5px=1物理像素,你可以直接使用設(shè)計師標注的參數(shù)加上rpx即可。

上面的width:17rpx表示無論在什么樣的移動設(shè)備上,其大小都為750份中的17份,寬屏則顯示大一些,窄屏則顯示小一些,視覺效果一致。

按Ctrl+S鍵保存現(xiàn)有代碼,模擬器即時顯示出了目前的頁面效果:3顆黃星、1顆半星、1顆灰星。

img

在wxml文件中,我們在內(nèi)寫了5個靜態(tài)的image圖像控件。然而在實際場景中,這個不可能是寫死的,而應(yīng)該是根據(jù)電影的不同評分進行相應(yīng)的顯示。

動態(tài)數(shù)據(jù)涉及到一些數(shù)據(jù)綁定等相關(guān)的知識,這里先簡要介紹一下。

數(shù)據(jù)綁定

{{}}

WXML 中的動態(tài)數(shù)據(jù)均來自對應(yīng) Page 的 data,數(shù)據(jù)綁定使用 Mustache 語法(雙大括號)將變量包起來,如:

<view wx:for="{{count}}">
  <text>{{stars}}</text>
</view>

頁面渲染時,系統(tǒng)將去對應(yīng)頁面的js文件的data屬性中尋找count和stars變量。

條件渲染

wx:if

在框架中,使用 wx:if="{{條件語句}}" 來判斷是否需要渲染該代碼塊:

<image wx:if="{{stars>30}}" src='/images/ratingbar/star_fill_whole.png' />

上條語句表示當(dāng)滿足stars>30的條件時,渲染image控件。

除了if條件外,還有wx:elif 和 wx:else語句:

<image wx:if="{{stars>30}}" src='/images/ratingbar/star_fill_whole.png' />
<image wx:elif="{{stars>20}}" src='/images/ratingbar/star_fill_half.png' />
<image wx:else src='/images/ratingbar/star_fill_none.png' />

wx:if 有且只有一個;

wx:elif 是else if的意思,可以有多個;

wx:else 最多只有一個。

系統(tǒng)按順序判斷各個條件,遇到成立的條件時則渲染該控件,其余控件則不會渲染。

注意:內(nèi)部的條件語句的結(jié)果為{{false}}才表示條件不成立,不帶{{}}的值將會被視為文本從而判定為條件成立。

<view wx:if="{{false}}"/>   <!--條件不成立-->
<view wx:if="false"/>  <!--條件成立-->
<view wx:if="3"/>  <!--條件成立-->
列表渲染

wx:for

在組件上使用 wx:for 控制屬性綁定一個數(shù)組,即可使用數(shù)組中各項的數(shù)據(jù)重復(fù)渲染該組件。數(shù)組長度為多少,就會重復(fù)渲染多少次。

<block wx:for="{{count}}">
    <text>{{index}}:{{item}}</text>
</block>

在循環(huán)時,當(dāng)前項的變量名默認為 item,其下標變量名默認為 index。

<block wx:for="{{count1}}">
  <block wx:for="{{count2}}">
    <text>{{index}}:{{item}}</text>
  </block>
</block>

如果遇到這種多重循環(huán)呢,如何在內(nèi)部表示不同數(shù)組的當(dāng)前項和下標呢?

可以用wx:for-item和wx:for-index分別指定當(dāng)前項的變量名和下標的變量名:

<block wx:for="{{count1}}" wx:for-item="outer" wx:for-index="i">
  <block wx:for="{{count2}}" wx:for-item="inner" wx:for-index="j">
    <text>{{i}}:{{outer}}</text>
    <text>{{j}}:{{inner}}</text>
  </block>
</block>

數(shù)據(jù)綁定相關(guān)的知識大致了解了,我們打開ratingbar.js,并在data內(nèi)定義兩個變量:

// pages/movies/ratingbar/ratingbar.js
Page({
  data: {
    count:[3,5,6,8,9],
    stars:16
  }
})

然后將ratingbar.wxml文件內(nèi)容修改為:

<!--pages/movies/ratingbar/ratingbar.wxml-->
<view class='ratingbar-stars'>
  <!--count數(shù)組長度為5,共5次循環(huán)顯示5顆星星-->
  <block wx:for="{{count}}">
    <!--全黃星星-->
    <image wx:if="{{stars/10>=index+1}}" src='/images/ratingbar/star_fill_whole.png' />
    <!--半黃半灰星星-->
    <image wx:elif="{{stars/10>=index && stars%10!=0}}" src='/images/ratingbar/star_fill_half.png' />
    <!--全灰星星-->
    <image wx:else src='/images/ratingbar/star_fill_none.png' />
  </block>
</view>

按Ctrl+S保存看看模擬器的效果,把stars的值改為其它數(shù)(0-50之間)試試看星星的顯示效果吧。Tips:這里的條件語句是研究豆瓣電影API里電影評分的規(guī)律得來的。它的stars取值為0/5/10……40/45/50。

據(jù)我們之前對豆瓣評分小程序的分析,評分條一般作為一個元素在相關(guān)頁面中顯示,不會獨立作為頁面來顯示。小程序官方提供了機制來解決這種復(fù)用性的問題,代碼片段一處編寫,多處使用,極大地精簡了代碼的臃腫,也令程序員有更多精力專注于必要的地方。其結(jié)構(gòu)如下:

<template name="模板名稱">
  <!--這里是要復(fù)用的代碼片段-->
</template>

我們將剛才編寫的ratingbar.wxml代碼最外層加上模板標識:

<!--pages/movies/ratingbar/ratingbar.wxml-->
<template name="template-ratingbar-stars">
  <view class='ratingbar-stars'>
    <!--數(shù)組長度為5,共5次循環(huán)顯示5顆星星-->
    <block wx:for="{{[3,5,6,8,9]}}">
      <!--全黃星星-->
      <image wx:if="{{stars/10>=index+1}}" src='/images/ratingbar/star_fill_whole.png' />
      <!--半黃半灰星星-->
      <image wx:elif="{{stars/10>=index && stars%10!=0}}" src='/images/ratingbar/star_fill_half.png' />
      <!--全灰星星-->
      <image wx:else src='/images/ratingbar/star_fill_none.png' />
    </block>
  </view>
</template>

模板名稱是template-ratingbar-stars,在其它頁面引入本模板后,根據(jù)該名稱即可找到此模板。因為評分條有且只有5顆星星,所以這里將count的值直接寫在此處wx:for="{{[3,5,6,8,9]}}",然后我們把ratingbar.js中的相關(guān)值注釋掉:

Page({
  data: {
    // count:[3,5,6,8,9],
    // stars:16
  }
})

因為作為模板,將在多處調(diào)用,其所使用的值(如這里的stars)將由調(diào)用的地方傳入,也正因為這樣,才有復(fù)用性可言。其實,模板文件只有wxml和wxss有用,js和json文件刪除亦可。

電影海報模板

接下來,我們來編寫電影海報,就是藍框這個:

img
有多處使用了這樣的結(jié)構(gòu),顯然,也應(yīng)當(dāng)是一個模板文件。

我們可以參照編寫評分條模板的步驟,先將其當(dāng)作為一個頁面,配置在小程序的首頁,在js中模擬數(shù)據(jù),調(diào)試成功后,再改成模板頁面。

首先,在movies目錄下新建poster目錄和poster頁面,在app.json的pages屬性中,將poster頁面路徑放在首位(ratingbar路徑可以刪除),以便在模擬器中查看效果和調(diào)試。

{
  "pages": [
    "pages/movies/poster/poster",
    "pages/movies/ratingbar/ratingbar",
    "pages/movies/index",
    "pages/mine/mine"
  ],
   ……
}

在poster.js中寫入一些模擬數(shù)據(jù):

// pages/movies/poster/poster.js
Page({
  data: {
    title: "奇跡男孩 Wonder",
    images: {
      large: "https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2507709428.jpg"
    },
    rating: {
      average: 8.6,
      max: 10,
      min: 0,
      stars: "45"
    }
  }
})

我們將在頁面中通過綁定數(shù)據(jù)來獲取這些數(shù)據(jù),如電影名稱{{title}}、海報圖片{{images.large}}、電影評分{{rating.average}}等。

在poster.wxss中寫入:

/* 導(dǎo)入評分條模板wxss文件,注意是@import */
@import "../ratingbar/ratingbar.wxss";
.movie {
  display: flex;
  flex-direction: column;
  padding-right: 12rpx;  
}
.poster {
  width: 200rpx;
  height: 270rpx;
  padding-bottom: 10rpx;
}
.movie-name {
  color: #333333;
  font-size: 24rpx;
  line-height: 24rpx;
  margin: 10rpx 0 5rpx 0;
}
.ratingbar {
  display: flex;
  flex-direction: row;
}
.ratingbar-score{
  color: #999999;
  font-size: 20rpx;
}
模板的使用

這里用到了評分條模板,因此在開頭導(dǎo)入了評分條模板的wxss樣式。每個.樣式都對應(yīng)著下文相關(guān)控件的class。

在poster.wxml中寫入:

<!--導(dǎo)入評分條模板wxml文件,注意別少了后面的 / 符號-->
<import src="../ratingbar/ratingbar.wxml" />

<view class='movie' catchtap='catchTapMovie' data-movieid='{{id}}'>
  <!--海報圖-->
  <image class="poster" src='{{images.large}}'></image>
  <!--電影名稱-->
  <text class='movie-name'>{{title}}</text>
  <!--評分星星和數(shù)字-->
  <view class='ratingbar'>
    <!--評分條-->
    <template is="template-ratingbar-stars" data="{{...rating}}" />
    <!--評分分數(shù)-->
    <text class='ratingbar-score'>{{rating.average}}</text>
  </view>
</view>

同理,開頭也導(dǎo)入了評分條模板的wxml文件,并通過以下方式使用。

<!--評分條-->
<template is="template-ratingbar-stars" data="{{...rating}}" />

is屬性值正是評分條模板的name名稱,data值將相關(guān)數(shù)據(jù)傳入評分條模板。

poster.js的data屬性中含有rating數(shù)據(jù),其格式見下文。上文中的...rating即是將rating數(shù)據(jù)散開,將其內(nèi)容傳入評分條模板,評分條模板里可以直接使用{{stars}},而不需要通過{{rating.stars}}的方式。

rating: {
      average: 8.6,
      max: 10,
      min: 0,
      stars: "45"
    }

這里還出現(xiàn)了諸如下文的屬性名,我們將留到后面講解。

<view class='movie' catchtap='catchTapMovie' data-movieid='{{id}}'>

現(xiàn)在,將poster.js的data屬性中的模擬數(shù)據(jù)注釋或刪除掉,并將poster.wxml封裝成模版,如下文所示。

<!--導(dǎo)入評分條模板wxml文件,注意別少了后面的 / 符號-->
<import src="../ratingbar/ratingbar.wxml" />

<!--封裝成名稱為template-poster的模板-->
<template name="template-poster">
  <view class='movie' catchtap='catchTapMovie' data-movieid='{{id}}'>
    <!--海報圖-->
    <image class="poster" src='{{images.large}}'></image>
    <!--電影名稱-->
    <text class='movie-name'>{{title}}</text>
    <!--評分星星和數(shù)字-->
    <view class='ratingbar'>
      <!--評分條-->
      <template is="template-ratingbar-stars" data="{{...rating}}" />
      <!--評分分數(shù)-->
      <text class='ratingbar-score'>{{rating.average}}</text>
    </view>
  </view>
</template>

區(qū)塊模板

有了電影海報模板后,接下來我們進行下一步。觀察到首頁是由三個結(jié)構(gòu)一模一樣的紅色區(qū)塊組成,顯然,這也可以是一個模板,暫且稱之為block吧。

img

步驟和先前個模板一樣,為節(jié)省篇幅,這里會更簡略地以貼代碼為主。首頁在movies目錄下新建block目錄和頁面,并在app.json文件的pages中將block頁面的路徑移到首位,以便觀察模擬器效果。

在images目錄新建block目錄,放入下面這張名為arrow-right.png的右箭頭圖片。

img

在block.js文件的data屬性中寫入模擬的數(shù)據(jù)(如下),有兩個鍵值對,一為blockTitle區(qū)塊標題,一為blockMovies為區(qū)塊電影數(shù)據(jù)(與豆瓣API返回的格式一致,有刪減字段,但結(jié)構(gòu)不變)。

// pages/movies/block/block.js

Page({
  data: {
    blockTitle:"正在熱映",
    blockMovies: {
      "count": 4,
      "start": 0,
      "subjects": [{
        "casts": [{
          "avatars": {
            "large": "https://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1509423054.09.jpg"
          },
          "name": "阿德瓦·香登"
        },
        {
          "avatars": {
            "large": "https://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p13628.jpg"
          },
          "name": "阿米爾·汗"
        },
        {
          "avatars": {
            "large": "https://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1494080264.12.jpg"
          },
          "name": "塞伊拉·沃西"
        }
        ],
        "comments_count": 5951,
        "countries": [
          "印度"
        ],
        "directors": [{
          "avatars": {
            "large": null
          },
          "name": "阿德瓦·香登"
        }],
        "genres": [
          "劇情",
          "音樂"
        ],
        "id": 259,
        "images": {
          "large": "https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2508925590.jpg"
        },
        "original_title": "神秘巨星 Secret Superstar",
        "rating": {
          "average": 8.2,
          "max": 10,
          "min": 0,
          "stars": "40"
        },
        "reviews_count": 292,
        "summary": "14歲的印度少女尹希婭(塞伊拉·沃西 飾)熱愛唱歌,因父親阻撓,她只能蒙面拍攝并上傳自彈自唱原創(chuàng)歌曲的視頻,孰料憑借天籟歌喉在網(wǎng)上一炮而紅,備受爭議的音樂人夏克提·庫馬爾(阿米爾·汗 飾)也向她拋出橄欖枝,尹希婭的生活發(fā)生了翻天覆地的變化……",
        "title": "神秘巨星 Secret Superstar",
        "warning": "數(shù)據(jù)來源于網(wǎng)絡(luò)整理,僅供學(xué)習(xí),禁止他用。如有侵權(quán)請聯(lián)系公眾號:小樓昨夜又秋風(fēng)。我將及時刪除。",
        "wish_count": 22447,
        "year": 2017
      },
      {
        "casts": [{
          "avatars": {
            "large": "https://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p19485.jpg"
          },
          "name": "李芳芳"
        },
        {
          "avatars": {
            "large": "https://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1359895311.0.jpg"
          },
          "name": "章子怡"
        },
        {
          "avatars": {
            "large": "https://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1472787652.32.jpg"
          },
          "name": "黃曉明"
        }
        ],
        "comments_count": 58027,
        "countries": [
          "中國大陸"
        ],
        "directors": [{
          "avatars": {
            "large": null
          },
          "name": "李芳芳"
        }],
        "genres": [
          "劇情",
          "愛情",
          "戰(zhàn)爭"
        ],
        "id": 265,
        "images": {
          "large": "https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2507572275.jpg"
        },
        "original_title": "無問西東",
        "rating": {
          "average": 7.5,
          "max": 10,
          "min": 0,
          "stars": "40"
        },
        "reviews_count": 4354,
        "summary": "如果提前了解了你所要面對的人生,你是否還會有勇氣前來?吳嶺瀾、沈光耀、王敏佳、陳鵬、張果果,幾個年輕人滿懷諸多渴望,在四個非同凡響的時空中一路前行。\\n吳嶺瀾(陳楚生 飾),出發(fā)時意氣風(fēng)發(fā),卻很快在途中迷失了方向。沈光耀(王力宏 飾),自愿參與了最殘酷的戰(zhàn)爭,他一直在努力去做那些令他害怕,但重要的事。王敏佳(章子怡 飾)最初的錯誤,只是為了虛榮撒了一個小謊;最初的煩惱,只是在兩個優(yōu)秀的男人中選擇一個。但命運,卻把她拖入被眾人唾罵的深淵。陳鵬(黃曉明 飾)把愛情擺在了理想前面,但愛情卻沒有把他擺在前面。他說,“我有人要照顧”,縱然這意味著與所有人作對,意味著要和她一起被放逐千里。張果果(張震 飾),身處爾虞我詐的職場,“贏”是他的習(xí)慣。為了贏,他總是見招拆招,先發(fā)制人。而有一天,他卻面臨了一個比“贏”更重要的選擇。這幾個年輕人,在最好的年紀迎來了最殘酷的...",
        "title": "無問西東",
        "warning": "數(shù)據(jù)來源于網(wǎng)絡(luò)整理,僅供學(xué)習(xí),禁止他用。如有侵權(quán)請聯(lián)系公眾號:小樓昨夜又秋風(fēng)。我將及時刪除。",
        "wish_count": 32890,
        "year": 2018
      },
      {
        "casts": [{
          "avatars": {
            "large": "https://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p57551.jpg"
          },
          "name": "斯蒂芬·卓博斯基"
        },
        {
          "avatars": {
            "large": "https://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1456737567.18.jpg"
          },
          "name": "雅各布·特倫布萊"
        },
        {
          "avatars": {
            "large": "https://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p8889.jpg"
          },
          "name": "朱莉婭·羅伯茨"
        }
        ],
        "comments_count": 4854,
        "countries": [
          "美國"
        ],
        "directors": [{
          "avatars": {
            "large": null
          },
          "name": "斯蒂芬·卓博斯基"
        }],
        "genres": [
          "劇情",
          "家庭",
          "兒童"
        ],
        "id": 269,
        "images": {
          "large": "https://img1.doubanio.com/view/photo/s_ratio_poster/public/p2507709428.jpg"
        },
        "original_title": "奇跡男孩 Wonder",
        "rating": {
          "average": 8.6,
          "max": 10,
          "min": 0,
          "stars": "45"
        },
        "reviews_count": 162,
        "summary": "電影《奇跡男孩》改編自全球暢銷小說《奇跡》,講述了一個溫暖千萬家庭的成長故事。10 歲的奧吉(雅各布·特倫布萊 Jacob Tremblay 飾)天生臉部畸形,此前一直在家中和媽媽(朱莉婭·羅伯茨 Julia Roberts 飾)自學(xué)。當(dāng)他小學(xué)五年級時,奧吉進入父母為他精心挑選的學(xué)校上學(xué)。在這里,奧吉將與校長、老師以及性格迥異的同學(xué)相處,他不尋常的外表讓他成為同學(xué)們討論的焦點,并終日受到嘲笑和排斥,就連好不容易交到的新朋友也似乎不太值得信任。幸運的是,在成長過程中,奧吉的父母、姐姐一直是他最堅強的后盾,在他們的支持與關(guān)愛下,奧吉憑借自身的勇氣、善良、聰敏影響激勵了許多身邊的人,并收獲了友誼、尊重與愛,最終成長為大家心目中的不可思議的“奇跡”。",
        "title": "奇跡男孩 Wonder",
        "warning": "數(shù)據(jù)來源于網(wǎng)絡(luò)整理,僅供學(xué)習(xí),禁止他用。如有侵權(quán)請聯(lián)系公眾號:小樓昨夜又秋風(fēng)。我將及時刪除。",
        "wish_count": 29417,
        "year": 2017
      },
      {
        "casts": [{
          "avatars": {
            "large": "https://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p20143.jpg"
          },
          "name": "丁晟"
        },
        {
          "avatars": {
            "large": "https://img1.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1509429399.29.jpg"
          },
          "name": "王凱"
        },
        {
          "avatars": {
            "large": "https://img3.doubanio.com/view/celebrity/s_ratio_celebrity/public/p1422629943.25.jpg"
          },
          "name": "馬天宇"
        }
        ],
        "comments_count": 6927,
        "countries": [
          "中國大陸",
          "香港"
        ],
        "directors": [{
          "avatars": {
            "large": null
          },
          "name": "丁晟"
        }],
        "genres": [
          "劇情",
          "動作"
        ],
        "id": 260,
        "images": {
          "large": "https://img3.doubanio.com/view/photo/s_ratio_poster/public/p2508615612.jpg"
        },
        "original_title": "英雄本色2018",
        "rating": {
          "average": 5.2,
          "max": 10,
          "min": 0,
          "stars": "25"
        },
        "reviews_count": 711,
        "summary": "周凱(王凱 飾)參與走私,被身為緝毒警察的弟弟周超(馬天宇 飾)逮捕入獄。三年后,周凱出獄,改過自新。曾經(jīng)的手下阿倉(余皚磊 飾)已為毒販頭目,為獲取周凱的海外客戶資料,設(shè)計加害周凱。江湖中的好兄弟馬柯(王大陸 飾)為了替周凱報仇,失去一條腿。自己的親弟弟周超不相信哥哥周凱已金盆洗手,不斷搜集證據(jù),欲親手逮捕周凱。最終,周凱與警方合作,逮捕了阿倉,兩兄弟重歸于好。",
        "title": "英雄本色2018",
        "warning": "數(shù)據(jù)來源于網(wǎng)絡(luò)整理,僅供學(xué)習(xí),禁止他用。如有侵權(quán)請聯(lián)系公眾號:小樓昨夜又秋風(fēng)。我將及時刪除。",
        "wish_count": 4552,
        "year": 2018
      }
      ]
    }
  }
})

在block.wxss文件中寫入以下數(shù)據(jù):

/* pages/movies/block/block.wxss */

/* 導(dǎo)入電影海報模板的WXSS */
@import "../poster/poster.wxss";

.block-title-bar {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  padding: 30rpx 20rpx 0rpx 20rpx;
}

.block-title {
  color: #333333;
  font-size: 30rpx;
}

.block-more {
  display: flex;
  flex-direction: row;
  align-items: center;
}

.block-more-text {
  color: #ffae00;
  font-size: 24rpx;
}

.block-more-icon {
  width: 12rpx;
  height: 20rpx;
  padding-left: 6rpx; 
}

.block-scroll-view {
  display: flex;
  flex-direction: row;
}

.block-movie-row{
  display: flex;
  flex-direction: row;
  padding: 20rpx 0 20rpx 20rpx;
}

.block-movie-card {
  display: flex;
  flex-direction: row;
  margin-right: 10rpx;
}

在block.wxml中寫入:

<!--pages/movies/block/block.wxml-->

<!--導(dǎo)入電影海報模板-->
<import src="../poster/poster.wxml" />

<view>
  <!--區(qū)塊頂欄-->
  <view class='block-title-bar'>
    <!--類別標題,如正在熱映-->
    <text class='block-title'>{{blockTitle}}</text>
    <view class='block-more' catchtap='catchMore' data-title='{{blockTitle}}'>
      <!--更多-->
      <text class='block-more-text'>更多</text>
      <!--右箭頭-->
      <image class='block-more-icon' src='/images/block/arrow-right.png'></image>
    </view>
  </view>
  <!--電影海報展示條-->
  <scroll-view scroll-x="{{true}}" class='block-scroll-view'>
    <view class='block-movie-row'>
      <block wx:for="{{blockMovies.subjects}}" wx:for-item="poster">
        <!--單個電影海報-->
        <view class='block-movie-card'>
          <template is="template-poster" data="{{...poster}}" />
        </view>
      </block>
    </view>
  </scroll-view>
</view>

按Ctrl+S保存后,模擬器效果如下。第一個出現(xiàn)了電影名稱過長的情形,我們后續(xù)會寫一個stringUtil.js的工具類來截斷。

img

我們在block頁面導(dǎo)入了poster模板的wxml和wxss文件,并通過下文代碼使用了。

<!--導(dǎo)入電影海報模板-->
<import src="../poster/poster.wxml" />
……
<!--電影海報展示條-->
<scroll-view scroll-x="{{true}}" class='block-scroll-view'>
    <view class='block-movie-row'>
      <block wx:for="{{blockMovies.subjects}}" wx:for-item="poster">
        <!--單個電影海報-->
        <view class='block-movie-card'>
          <template is="template-poster" data="{{...poster}}" />
        </view>
      </block>
    </view>
  </scroll-view>
 ……

這里使用了一個新的控件滑動條,有scroll-x和scroll-y屬性,用以設(shè)定滑動的方向是水平還是豎直。

在滑動條內(nèi)部,通過wx:for循環(huán)取出blockMovies.subjects的值,用poster表示當(dāng)前項。

電影海報通過海報模板導(dǎo)入,通過{{...poster}}的形式散開poster的值傳入海報模板中,為海報模板中的同名變量提供對應(yīng)的值。

<!--類別標題,如正在熱映-->
<text class='block-title'>{{blockTitle}}</text>
<view class='block-more' catchtap='catchMore' data-title='{{blockTitle}}'>

在上文中又出現(xiàn)了catchtap和data-形式的屬性名,這是界面上“更多”按鈕的點擊事件和自定義屬性,后文詳細講解。

最后將block.js中data里的相關(guān)數(shù)據(jù)注釋或刪除,并在block.wxml里封裝模板。

<!--導(dǎo)入電影海報模板-->
<import src="../poster/poster.wxml" />

<!--封裝成區(qū)塊模板-->
<template name="template-block">
    <view>
      ……
    </view>
</template>

別忘了在app.json文件的data屬性中將主頁的路徑“pages/movies/index”提到首位,我們即將要編寫主頁了。

到目前為止,我們所需要的三個模板已經(jīng)全部封裝完了。

block模板里導(dǎo)入了poster模板,后者又嵌入了ratingbar模板,極大的精簡了相關(guān)的代碼,加強了代碼的易維護性。不信?看主頁,我們只需寥寥數(shù)行代碼即可。

下篇:https://mp.weixin.qq.com/s/Isfk9s2cgtyXdh5Olap9QA

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內(nèi)容