邊做邊學入門微信小程式之仿豆瓣評分

Xcwer發表於2018-03-23

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

為了貼合實際的應用情況,本篇以豆瓣評分小程式為參考樣例,邊做邊學小程式的入門開發知識。

目錄

效果圖
Demo原始碼
開發環境
瞭解官方樣例
開發者工具
樣例原始碼結構
開發實戰
底部Tab卡頁
分析開發需求
評分條模板
rpx長度單位
資料繫結
條件渲染
列表渲染
電影海報模板
模板的使用
區塊模板
主頁
網路請求
邏輯實現
setData
點選事件
詳情頁
更多頁
擴充套件知識
思考題
複製程式碼

效果圖

先看一下對比效果圖,共三個頁面,分別為首頁、更多頁和詳情頁,左側為豆瓣評分官方小程式,右側為仿作。因API資料問題,沒有做搜尋功能。

主頁

img
img

更多頁

img
img

詳情頁

img
img

Demo原始碼

本篇完整原始碼已提交在: github.com/cnwen/wecha…

開發環境

除錯基礎庫:1.9.91(2018.03.07)

微信開發者工具:Windows版v1.02.1802270

瞭解官方樣例

開啟微信開發者工具,新建一個小程式專案。

1.選擇專案程式碼存放的目錄;

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

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

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

img
img

開發者工具

我們觀察開發者工具,發現由三個主要區域構成,分別是模擬器、編輯器和偵錯程式。

img
img

模擬器:頂端含有三個下拉選單,可以配置模擬的機型和所處的網路環境。

編輯器:分為原始碼目錄區域和程式碼區域。

偵錯程式:頂端含有控制檯、網路、儲存等選項卡頁。

樣例原始碼結構

根目錄含有pages、utils資料夾和三個名稱為app的檔案。顧名思義,pages正是存放小程式各個頁面的資料夾,一些公共的工具類建議放在utils資料夾,app檔案是小程式的全域性檔案。

點選檢視app.json檔案的原始碼,可以看到含有pages和window兩個鍵值對。

img
img

pages負責配置小程式的頁面,裡面有2條路徑,分別對應index和logs頁面。

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

window負責全域性的視窗配置,如導航欄背景色、導航欄文字等。你可以修改它們的值,儲存後在模擬器上看到效果。

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

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

回到原始碼目錄,對比index和logs頁面的構成,發現index頁面並沒有.json檔案,可見這個檔案並非是必須的。但是,如果有這個檔案,那麼必然不能為空,否則控制檯會報錯,可在裡面寫入一個大括號{}儲存即可。

開發實戰

官方樣例先認識到這裡,我們對開發者工具和小程式原始碼構成有了一個初步的印象後,開始邊做邊學。

底部Tab卡頁

我們使用滑鼠右鍵將原始碼目錄pages下的index/logs兩個資料夾刪除,並開啟app.json,在pages的值中配置下圖中的兩條路徑。

img
img

按Ctrl+S鍵儲存,開發者工具將自動在指定路徑為我們建立兩個頁面,如下圖所示。

img
img

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

img
img

如果我們要檢視mine頁面怎麼辦呢?除了使用後文將提到的頁面跳轉功能,這裡用Tab卡頁的切換功能來試試。在app.json檔案中新增tabBar內容,如下所示。

{
"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"
}
}
複製程式碼

模擬器預覽效果如下圖:

img
img

在list的值中,我們配置了2個卡頁,text是卡頁的文字,pathPath代表了頁面路徑,當點選卡頁時,將跳轉到指定路徑的頁面。注意卡頁數必須為2-5個才合規,否則控制檯會報錯。並且,這裡的路徑必須被包含在頂端的pages值中,因為所有可抵達頁面都必須在pages中配置路徑。

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

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

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

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

img
img
img
img

一個為預設圖示,一個是選中時顯示的圖示。(請看圖示路徑,我在左側目錄樹的根目錄新建了images/tabbar目錄,並放入了4張圖示,圖示資源在Github原始碼中有)

這樣,首頁Tab便完成了。接下來我們來分析頁面結構,並實現一些公用的template模板檔案。

分析開發需求

作為編碼者,在開始編碼之前,我們要養成先從整體層面上分析整體需求的好習慣,有利於後續的程式碼編寫及維護。

img
img

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

評分條模板

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

從上面的分析中,我們發現這裡提到的三個模板是層層巢狀的,因此,作為入門學習者,我們先從最內層的模板開始實現,即先實現評分條ratingbar模板檔案。

img
img

評分星星有三種狀態,我們在images目錄中新建ratingbar目錄,並將這三個星星圖示放入。(Github原始碼中含有本文所需的所有素材)

img
img

在movies目錄右鍵滑鼠,依次新建名為ratingbar的目錄和Page。開啟app.json檔案,我們發現開發者工具自動在pages值為我們配置了ratingbar頁面的路徑。

img
img

作為模板檔案,是在其它頁面中匯入使用的,它不會單獨被使用,因此其實它不需要在app.json的pages值中配置路徑,並且該頁面只需wxml和wxss即可,js和json檔案都是用不上的,它所含的頁面元素的資料和行為都是由引用它的頁面來操縱的,後文會對此有所涉及。

但在此時,我們需要在模擬器中除錯、檢視其效果,所以要將它當作單獨頁面來使用一次,除錯完後可將js/json檔案刪除,並刪除在app.json中pages值中的路徑,此是後話,暫且略過。

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

img
img

頁面上唯一的一條內容是由開發者工具在新建頁面時自動生成的。我們開啟ratingbar.wxml頁面,將自動生成的標籤內容刪除,並輸入以下內容,按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>
複製程式碼

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

這裡src的路徑出現了2種寫法,絕對路徑和相對路徑,如果不瞭解的可另外擴充一下,這裡的路徑是一樣的。

再點開ratingbar.wxss檔案,並輸入以下內容:

/* 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相呼應,將會用於渲染該控制元件。

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

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

rpx長度單位

rpx是微信小程式推出的單位,可以根據不同手機不同的螢幕寬度進行內容自適應,使頁面元素在不同螢幕寬度的手機上看起來具有一致性。

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

上面的width:17rpx表示無論在什麼樣的移動裝置上,其大小都為750份中的17份,寬屏則顯示大一些,窄屏則顯示小一些,視覺效果一致。

按Ctrl+S鍵儲存現有程式碼,模擬器即時顯示出了目前的頁面效果:3顆黃星、1顆半星、1顆灰星。

img
img

在wxml檔案中,我們在內寫了5個靜態的image影象控制元件。然而在實際場景中,這個不可能是寫死的,而應該是根據電影的不同評分進行相應的顯示。

動態資料涉及到一些資料繫結等相關的知識,這裡先簡要介紹一下。

資料繫結

{{}}

WXML 中的動態資料均來自對應 Page 的 data,資料繫結使用 Mustache 語法(雙大括號)將變數包起來,如:

<view wx:for="{{count}}">
<text>{{stars}}</text>
</view>
複製程式碼

頁面渲染時,系統將去對應頁面的js檔案的data屬性中尋找count和stars變數。

條件渲染

wx:if

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

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

上條語句表示當滿足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 最多隻有一個。

系統按順序判斷各個條件,遇到成立的條件時則渲染該控制元件,其餘控制元件則不會渲染。

注意:內部的條件語句的結果為{{false}}才表示條件不成立,不帶{{}}的值將會被視為文字從而判定為條件成立。

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

wx:for

在元件上使用 wx:for 控制屬性繫結一個陣列,即可使用陣列中各項的資料重複渲染該元件。陣列長度為多少,就會重複渲染多少次。

<block wx:for="{{count}}">
<text>{{index}}:{{item}}</text>
</block>
複製程式碼

在迴圈時,當前項的變數名預設為 item,其下標變數名預設為 index。

<block wx:for="{{count1}}">
<block wx:for="{{count2}}">
<text>{{index}}:{{item}}</text>
</block>
</block>
複製程式碼

如果遇到這種多重迴圈呢,如何在內部表示不同陣列的當前項和下標呢?

可以用wx:for-item和wx:for-index分別指定當前項的變數名和下標的變數名:

<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>
複製程式碼

資料繫結相關的知識大致瞭解了,我們開啟ratingbar.js,並在data內定義兩個變數:

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

然後將ratingbar.wxml檔案內容修改為:

<!--pages/movies/ratingbar/ratingbar.wxml-->
<view class='ratingbar-stars'>
<!--count陣列長度為5,共5次迴圈顯示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的值改為其它數(0-50之間)試試看星星的顯示效果吧。Tips:這裡的條件語句是研究豆瓣電影API裡電影評分的規律得來的。它的stars取值為0/5/10……40/45/50。

據我們之前對豆瓣評分小程式的分析,評分條一般作為一個元素在相關頁面中顯示,不會獨立作為頁面來顯示。小程式官方提供了機制來解決這種複用性的問題,程式碼片段一處編寫,多處使用,極大地精簡了程式碼的臃腫,也令程式設計師有更多精力專注於必要的地方。其結構如下:

<template name="模板名稱">
<!--這裡是要複用的程式碼片段-->
</template>
複製程式碼

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

<!--pages/movies/ratingbar/ratingbar.wxml-->
<template name="template-ratingbar-stars">
<view class='ratingbar-stars'>
<!--陣列長度為5,共5次迴圈顯示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,在其它頁面引入本模板後,根據該名稱即可找到此模板。因為評分條有且只有5顆星星,所以這裡將count的值直接寫在此處wx:for="{{[3,5,6,8,9]}}",然後我們把ratingbar.js中的相關值註釋掉:

Page({
data: {
// count:[3,5,6,8,9],
// stars:16
}
})
複製程式碼

因為作為模板,將在多處呼叫,其所使用的值(如這裡的stars)將由呼叫的地方傳入,也正因為這樣,才有複用性可言。其實,模板檔案只有wxml和wxss有用,js和json檔案刪除亦可。

電影海報模板

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

img
img
有多處使用了這樣的結構,顯然,也應當是一個模板檔案。

我們可以參照編寫評分條模板的步驟,先將其當作為一個頁面,配置在小程式的首頁,在js中模擬資料,除錯成功後,再改成模板頁面。

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

{
"pages": [
"pages/movies/poster/poster",
"pages/movies/ratingbar/ratingbar",
"pages/movies/index",
"pages/mine/mine"
],
……
}
複製程式碼

在poster.js中寫入一些模擬資料:

// 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"
}
}
})
複製程式碼

我們將在頁面中通過繫結資料來獲取這些資料,如電影名稱{{title}}、海報圖片{{images.large}}、電影評分{{rating.average}}等。

在poster.wxss中寫入:

/* 匯入評分條模板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;
}
複製程式碼
模板的使用

這裡用到了評分條模板,因此在開頭匯入了評分條模板的wxss樣式。每個.樣式都對應著下文相關控制元件的class。

在poster.wxml中寫入:

<!--匯入評分條模板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>
<!--評分星星和數字-->
<view class='ratingbar'>
<!--評分條-->
<template is="template-ratingbar-stars" data="{{...rating}}" />
<!--評分分數-->
<text class='ratingbar-score'>{{rating.average}}</text>
</view>
</view>
複製程式碼

同理,開頭也匯入了評分條模板的wxml檔案,並通過以下方式使用。

<!--評分條-->
<template is="template-ratingbar-stars" data="{{...rating}}" />
複製程式碼

is屬性值正是評分條模板的name名稱,data值將相關資料傳入評分條模板。

poster.js的data屬性中含有rating資料,其格式見下文。上文中的…rating即是將rating資料散開,將其內容傳入評分條模板,評分條模板裡可以直接使用{{stars}},而不需要通過{{rating.stars}}的方式。

rating: {
average: 8.6,
max: 10,
min: 0,
stars: "45"
}
複製程式碼

這裡還出現了諸如下文的屬性名,我們將留到後面講解。

<view class='movie' catchtap='catchTapMovie' data-movieid='{{id}}'>
複製程式碼

現在,將poster.js的data屬性中的模擬資料註釋或刪除掉,並將poster.wxml封裝成模版,如下文所示。

<!--匯入評分條模板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>
<!--評分星星和數字-->
<view class='ratingbar'>
<!--評分條-->
<template is="template-ratingbar-stars" data="{{...rating}}" />
<!--評分分數-->
<text class='ratingbar-score'>{{rating.average}}</text>
</view>
</view>
</template>
複製程式碼

區塊模板

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

img
img

步驟和先前個模板一樣,為節省篇幅,這裡會更簡略地以貼程式碼為主。首頁在movies目錄下新建block目錄和頁面,並在app.json檔案的pages中將block頁面的路徑移到首位,以便觀察模擬器效果。

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

img
img

在block.js檔案的data屬性中寫入模擬的資料(如下),有兩個鍵值對,一為blockTitle區塊標題,一為blockMovies為區塊電影資料(與豆瓣API返回的格式一致,有刪減欄位,但結構不變)。

// 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歲的印度少女尹希婭(塞伊拉·沃西 飾)熱愛唱歌,因父親阻撓,她只能蒙面拍攝並上傳自彈自唱原創歌曲的視訊,孰料憑藉天籟歌喉在網上一炮而紅,備受爭議的音樂人夏克提·庫馬爾(阿米爾·汗 飾)也向她丟擲橄欖枝,尹希婭的生活發生了翻天覆地的變化……",
"title": "神祕巨星 Secret Superstar",
"warning": "資料來源於網路整理,僅供學習,禁止他用。如有侵權請聯絡公眾號:小樓昨夜又秋風。我將及時刪除。",
"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": [
"劇情",
"愛情",
"戰爭"
],
"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吳嶺瀾(陳楚生 飾),出發時意氣風發,卻很快在途中迷失了方向。沈光耀(王力巨集 飾),自願參與了最殘酷的戰爭,他一直在努力去做那些令他害怕,但重要的事。王敏佳(章子怡 飾)最初的錯誤,只是為了虛榮撒了一個小謊;最初的煩惱,只是在兩個優秀的男人中選擇一個。但命運,卻把她拖入被眾人唾罵的深淵。陳鵬(黃曉明 飾)把愛情擺在了理想前面,但愛情卻沒有把他擺在前面。他說,“我有人要照顧”,縱然這意味著與所有人作對,意味著要和她一起被放逐千里。張果果(張震 飾),身處爾虞我詐的職場,“贏”是他的習慣。為了贏,他總是見招拆招,先發制人。而有一天,他卻面臨了一個比“贏”更重要的選擇。這幾個年輕人,在最好的年紀迎來了最殘酷的...",
"title": "無問西東",
"warning": "資料來源於網路整理,僅供學習,禁止他用。如有侵權請聯絡公眾號:小樓昨夜又秋風。我將及時刪除。",
"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 飾)自學。當他小學五年級時,奧吉進入父母為他精心挑選的學校上學。在這裡,奧吉將與校長、老師以及性格迥異的同學相處,他不尋常的外表讓他成為同學們討論的焦點,並終日受到嘲笑和排斥,就連好不容易交到的新朋友也似乎不太值得信任。幸運的是,在成長過程中,奧吉的父母、姐姐一直是他最堅強的後盾,在他們的支援與關愛下,奧吉憑藉自身的勇氣、善良、聰敏影響激勵了許多身邊的人,並收穫了友誼、尊重與愛,最終成長為大家心目中的不可思議的“奇蹟”。",
"title": "奇蹟男孩 Wonder",
"warning": "資料來源於網路整理,僅供學習,禁止他用。如有侵權請聯絡公眾號:小樓昨夜又秋風。我將及時刪除。",
"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": "周凱(王凱 飾)參與走私,被身為緝毒警察的弟弟周超(馬天宇 飾)逮捕入獄。三年後,周凱出獄,改過自新。曾經的手下阿倉(餘皚磊 飾)已為毒販頭目,為獲取周凱的海外客戶資料,設計加害周凱。江湖中的好兄弟馬柯(王大陸 飾)為了替周凱報仇,失去一條腿。自己的親弟弟周超不相信哥哥周凱已金盆洗手,不斷蒐集證據,欲親手逮捕周凱。最終,周凱與警方合作,逮捕了阿倉,兩兄弟重歸於好。",
"title": "英雄本色2018",
"warning": "資料來源於網路整理,僅供學習,禁止他用。如有侵權請聯絡公眾號:小樓昨夜又秋風。我將及時刪除。",
"wish_count": 4552,
"year": 2018
}
]
}
}
})
複製程式碼

在block.wxss檔案中寫入以下資料:

/* pages/movies/block/block.wxss */
/* 匯入電影海報模板的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-->
<!--匯入電影海報模板-->
<import src="../poster/poster.wxml" />
<view>
<!--區塊頂欄-->
<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儲存後,模擬器效果如下。第一個出現了電影名稱過長的情形,我們後續會寫一個stringUtil.js的工具類來截斷。

img
img

我們在block頁面匯入了poster模板的wxml和wxss檔案,並通過下文程式碼使用了。

<!--匯入電影海報模板-->
<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屬性,用以設定滑動的方向是水平還是豎直。

在滑動條內部,通過wx:for迴圈取出blockMovies.subjects的值,用poster表示當前項。

電影海報通過海報模板匯入,通過{{…poster}}的形式散開poster的值傳入海報模板中,為海報模板中的同名變數提供對應的值。

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

在上文中又出現了catchtap和data-形式的屬性名,這是介面上“更多”按鈕的點選事件和自定義屬性,後文詳細講解。

最後將block.js中data裡的相關資料註釋或刪除,並在block.wxml裡封裝模板。

<!--匯入電影海報模板-->
<import src="../poster/poster.wxml" />
<!--封裝成區塊模板-->
<template name="template-block">
<view>
……
</view>
</template>
複製程式碼

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

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

block模板裡匯入了poster模板,後者又嵌入了ratingbar模板,極大的精簡了相關的程式碼,加強了程式碼的易維護性。不信?看主頁,我們只需寥寥數行程式碼即可。

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

邊做邊學入門微信小程式之仿豆瓣評分

相關文章