邊作邊學入門微信小程序之仿豆瓣評分

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

爲了貼合實際的應用狀況,本篇以豆瓣評分小程序爲參考樣例,邊作邊學小程序的入門開發知識。git

目錄程序員

效果圖
Demo源碼
開發環境
瞭解官方樣例
開發者工具
樣例源碼結構
開發實戰
底部Tab卡頁
分析開發需求
評分條模板
rpx長度單位
數據綁定
條件渲染
列表渲染
電影海報模板
模板的使用
區塊模板
主頁
網絡請求
邏輯實現
setData
點擊事件
詳情頁
更多頁
擴展知識
思考題

效果圖

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

主頁json

 

imgimg小程序

 

更多頁微信小程序

 

imgimg數組

 

詳情頁ruby

 

imgimgbash

 

Demo源碼

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

開發環境

調試基礎庫:1.9.91(2018.03.07)

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

瞭解官方樣例

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

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

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

3.勾選「創建普通快速啓動模板」。

點擊「肯定」按鈕後,開發者工具將爲咱們創建一個簡單的小程序模板,咱們能夠經過這個樣例來創建對開發者工具和小程序的初步認識。

imgimg

 

開發者工具

咱們觀察開發者工具,發現由三個主要區域構成,分別是模擬器、編輯器和調試器。

 

imgimg

 

模擬器:頂端含有三個下拉列表,能夠配置模擬的機型和所處的網絡環境。

編輯器:分爲源碼目錄區域和代碼區域。

調試器:頂端含有控制檯、網絡、存儲等選項卡頁。

樣例源碼結構

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

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

 

imgimg

 

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的值中配置下圖中的兩條路徑。

 

imgimg

 

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

imgimg

 

此時,模擬器中的首頁已經變成了movies目錄下的index頁面,由於咱們剛纔把這個頁面的路徑配置在app.json文件中pages值的首位了。

imgimg

 

若是咱們要查看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"
}
}

模擬器預覽效果以下圖:

imgimg

 

在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"
}

 

imgimgimgimg

 

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

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

分析開發需求

做爲編碼者,在開始編碼以前,咱們要養成先從總體層面上分析總體需求的好習慣,有利於後續的代碼編寫及維護。

 

imgimg

 

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

評分條模板

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

從上面的分析中,咱們發現這裏提到的三個模板是層層嵌套的,所以,做爲入門學習者,咱們先從最內層的模板開始實現,即先實現評分條ratingbar模板文件。

 

imgimg

 

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

 

imgimg

 

在movies目錄右鍵鼠標,依次新建名爲ratingbar的目錄和Page。打開app.json文件,咱們發現開發者工具自動在pages值爲咱們配置了ratingbar頁面的路徑。

 

imgimg

 

做爲模板文件,是在其它頁面中導入使用的,它不會單獨被使用,所以其實它不須要在app.json的pages值中配置路徑,而且該頁面只需wxml和wxss便可,js和json文件都是用不上的,它所含的頁面元素的數據和行爲都是由引用它的頁面來操縱的,後文會對此有所涉及。

但在此時,咱們須要在模擬器中調試、查看其效果,因此要將它看成單獨頁面來使用一次,調試完後可將js/json文件刪除,並刪除在app.json中pages值中的路徑,此是後話,暫且略過。

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

 

imgimg

 

頁面上惟一的一條內容是由開發者工具在新建頁面時自動生成的。咱們打開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顆灰星。

 

imgimg

 

在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文件刪除亦可。

電影海報模板

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

imgimg有多處使用了這樣的結構,顯然,也應當是一個模板文件。

 

咱們能夠參照編寫評分條模板的步驟,先將其看成爲一個頁面,配置在小程序的首頁,在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吧。

 

imgimg

 

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

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

imgimg

 

在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的工具類來截斷。

 

imgimg

 

咱們在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

相關文章
相關標籤/搜索