微(wei)信小(xiao)程序面世以(yi)來受(shou)到(dao)的關(guan)注頗多,直(zhi)到(dao)最近我才動手(shou)嘗試進行了小(xiao)程序的開(kai)(kai)發,總體上感(gan)覺還是(shi)不錯的,有一點不適應(ying)的就(jiu)是(shi)要(yao)擺脫Web APP開(kai)(kai)發對DOM的操(cao)作。在這里我就(jiu)把我是(shi)如何利(li)用API開(kai)(kai)發微(wei)信小(xiao)程序的過程寫成(cheng)教程 ...
微(wei)信小程(cheng)序(xu)面世以來受(shou)到的(de)(de)關(guan)注頗多(duo),直(zhi)到最近(jin)我才(cai)動手嘗(chang)試進行了小程(cheng)序(xu)的(de)(de)開發(fa)(fa),總體上(shang)感覺還是不(bu)錯的(de)(de),有一(yi)點(dian)不(bu)適應的(de)(de)就是要(yao)擺脫Web APP開發(fa)(fa)對DOM的(de)(de)操作。在這里我就把(ba)我是如何利用(yong)API開發(fa)(fa)微(wei)信小程(cheng)序(xu)的(de)(de)過程(cheng)寫(xie)成教程(cheng),教大家快(kuai)速(su)上(shang)手體驗一(yi)次微(wei)信小程(cheng)序(xu)的(de)(de)開發(fa)(fa)。
在開(kai)始之前我們先(xian)來看下成品的效(xiao)果圖(tu)

我(wo)們先確定想要開發一款(kuan)什(shen)么樣的(de)小(xiao)程(cheng)序,首先要符合「小(xiao)」,因為我(wo)們這次是要體驗小(xiao)程(cheng)序的(de)開發,所以盡量(liang)不(bu)要弄得太復雜;其(qi)次是「快」,小(xiao)程(cheng)序里需要的(de)數據啊、資源啊,最(zui)好是現成(cheng)就(jiu)有的(de),自(zi)己寫個(ge)API什(shen)么的(de)這就(jiu)太耗時了(le),就(jiu)不(bu)叫(jiao)快速(su)上手(shou)了(le)。
所以(yi)呢,如果能調(diao)用(yong)(yong)現成(cheng)的(de)API那是極好的(de),經過一(yi)番挑選(xuan),我選(xuan)擇了(le)聚合(he)數據的(de) 歷(li)史上的(de)今天 這個API,調(diao)用(yong)(yong)這個API獲取數據,我們只要(yao)做2個頁面就(jiu)可以(yi)完(wan)全展示(shi)出來了(le),又(you)(you)「小」又(you)(you)「快」哈XD
注(zhu): API需(xu)要注(zhu)冊(ce)之(zhi)后獲得KEY才能使(shi)用,具體請查看 聚合數據 官方(fang)文檔,這里(li)默(mo)認各位已(yi)經注(zhu)冊(ce)并擁(yong)有相應API所需(xu)的(de)KEY
微信開發者工具的安裝和使用在這里就不多(duo)作介(jie)紹(shao)了,有(you)疑問的話可以看微信官(guan)方的 簡易教程
先創建一個工程,依次點擊(ji)「添(tian)(tian)加項(xiang)目(mu)(mu)」--「無AppID」,然后填好「項(xiang)目(mu)(mu)名稱(cheng)」并選擇「項(xiang)目(mu)(mu)目(mu)(mu)錄」,點擊(ji)「添(tian)(tian)加項(xiang)目(mu)(mu)」

然(ran)后(hou)我們來(lai)清理一下默認(ren)工程(cheng)的目(mu)錄(lu)(lu)結構,刪除以下目(mu)錄(lu)(lu)和文件
pages/logs/ pages/index/index.wxss
創(chuang)建以下(xia)目(mu)錄和文件
pages/logs/ pages/index/index.wxsspages/detail/ pages/detail/detail.js pages/detail/detail.wxml pages/templates/ pages/templates/item.wxml res/
現在你看到的(de)目錄結構應該(gai)是這樣(yang)子的(de)
.
├── app.js
├── app.json
├── app.wxss
├── pages
│ ├── detail
│ │ ├── detail.js
│ │ └── detail.wxml
│ ├── index
│ │ ├── index.js
│ │ └── index.wxml
│ └── templates
│ └── item.wxml
├── res
└── utils
└── util.js
這就是我(wo)們工程目錄的(de)最終結構(gou)了,后面還會(hui)(hui)添(tian)加資源進(jin)去,但是整體結構(gou)還是這樣(yang)不會(hui)(hui)改變的(de)
微信小程序(xu)是(shi)通(tong)過修改 app.json 文件改變全局配(pei)(pei)置的(de),具體的(de)可配(pei)(pei)置項(xiang)請(qing)各位自行(xing)查(cha)閱小程序(xu)文檔的(de) 配(pei)(pei)置 一(yi)節
打開(kai) app.json ,修(xiu)改成
{
"pages":[
"pages/index/index",
"pages/detail/detail"
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#3e3e3e",
"navigationBarTitleText": "歷史今日",
"navigationBarTextStyle":"white"
},
"debug": true
}
我們(men)這里修改了導航(hang)欄的背景顏色(navigationBarBackgroundColor)、標(biao)題顏色(navigationBarTextStyle)以及標(biao)題內容(rong)(navigationBarTitleText),為了方便查(cha)看(kan)調(diao)試信息,我還(huan)開(kai)啟了debug模(mo)式(shi)
全(quan)局配置以(yi)及搞(gao)定(ding)啦,接(jie)下(xia)來(lai)正式開始編碼(ma)
前面已(yi)經說了我們(men)要做(zuo)的是「歷史上的今(jin)天(tian)」這樣的一(yi)個(ge)小程序,所以同一(yi)個(ge)日期會(hui)有(you)很多(duo)條(tiao)目,最常見的布局就是做(zuo)成列表(biao)
列表(biao)里(li)會有很多的條(tiao)目(mu),數量是(shi)不確定(ding)(ding)的,所以(yi)我(wo)們不能在(zai)頁(ye)面里(li)寫死了(le)布局,這時(shi)候就要用(yong)到 模板(template) 了(le),我(wo)們可以(yi)在(zai)模板中定(ding)(ding)義代碼片段,然后在(zai)不同的地方調用(yong)
我們來定(ding)義一個模板,打開 pages/templates/item.wxml ,添加代碼
<template name="tItem">
<navigator url="../detail/detail?id={{item.e_id}}">
<view class="ui-list-item ui-pure-item ui-border-b">
<view class="ui-item-span"><text>{{item.date}}</text></view>
<view class="ui-item-content ui-nowrap"><text>{{item.title}}</text></view>
</view>
</navigator>
</template>
注: 模(mo)板的使用細節請參考官方文檔 模(mo)板 一節
接下(xia)來打開 pages/index/index.wxml 刪掉里面(mian)的內(nei)容,我們(men)要在這里編寫列表頁,這里會使用(yong)到我們(men)上面(mian)定義的模板
<import src="../templates/item.wxml"/>
<scroll-view scroll-y="true" class="flex-row ui-list ui-border-t">
<template is="tItem" data="{{item}}" wx:for="{{events}}"/>
<view class="ui-tips">
<view wx:if="{{hidden}}"><text>沒有更多內容了</text></view>
<view wx:else><text>內容加載中...</text></view>
</view>
</scroll-view>
<loading hidden="{{hidden}}">Loading...</loading>
可(ke)以注(zhu)意到第一行使(shi)用(yong)了 import 將模(mo)板(ban)(ban)引(yin)入(ru)到頁面中,然后再使(shi)用(yong) is 屬性(xing),聲明需要使(shi)用(yong)的模(mo)板(ban)(ban),用(yong) data 屬性(xing)傳入(ru)數據供模(mo)板(ban)(ban)使(shi)用(yong)
注: 模板擁有自己的作用域,只能使(shi)用 data 傳入的數(shu)據
為了測試(shi)和查看布局效果,我們打開 pages/index/index.js 刪(shan)除里面的代碼(ma),然后添加以下代碼(ma)手動(dong)創建數據傳入給頁面渲(xuan)染
Page({
data: {
hidden: true,
events: [
{
date: "2016-10-14",
title: "TodayOnHistory, 歷史上的今天"
},
{
date: "2016-10-14",
title: "TodayOnHistory, 歷史上的今天"
},
{
date: "2016-10-14",
title: "TodayOnHistory, 歷史上的今天"
},
{
date: "2016-10-14",
title: "TodayOnHistory, 歷史上的今天"
},
{
date: "2016-10-14",
title: "TodayOnHistory, 歷史上的今天"
},
{
date: "2016-10-14",
title: "TodayOnHistory, 歷史上的今天"
}
]
}
})
保存(cun)后點擊開(kai)發工具左(zuo)側的編譯,即可查看到效果

注: 布局會用到圖(tu)標字(zi)(zi)體,導(dao)入到 res/ 下,樣式(shi)則寫在 app.wxss 全(quan)局樣式(shi)表中,圖(tu)標字(zi)(zi)體文件和樣式(shi)請從源碼中獲(huo)取,這篇教程不作樣式(shi)的(de)說明(ming)
首頁的(de)布局已經完成(cheng)了,暫時放(fang)下首頁列表(biao),接下來開(kai)始編寫詳細內容(rong)的(de)頁面
打開 pages/detail/detail.wxml ,添加(jia)內(nei)容(rong)如(ru)下
<view class="container">
<view class="ui-title ui-border-b"><text>{{detail.title}}</text></view>
<view class="ui-content"><text>{{detail.content}}</text></view>
<block wx:for="{{detail.picUrl}}">
<view>
<view><image mode="aspectFit" src="{{item.url}}"/></view>
<view class="ui-pic-title"><text>{{item.pic_title}}</text></view>
</view>
</block>
</view>
<loading hidden="{{hidden}}">Loading...</loading>
搞定(ding),這(zhe)個(ge)頁面就(jiu)這(zhe)么簡單(dan)就(jiu)OK了(le),現在我(wo)們打開 pages/detail/detail.js 手動(dong)添加數(shu)據到(dao)這(zhe)個(ge)頁面中查看效果(guo)
Page({
data:{
hidden: true,
detail: {
title: "歷史上的今天",
content: "歷史上的今天歷史上的今天歷史上的今天歷史上的今天歷史上的今天歷史上的今天歷史上的今天歷史上的今天歷史上的今天",
picUrl: [
{
url: "//sjbz.fd.zol-img.com.cn/t_s320x510c/g5/M00/00/04/ChMkJlfJWJCIYePaAAPdCld59MEAAU-KAP0U3gAA90i450.jpg",
pic_title: "這是圖片標題"
}
]
}
}
})

現在頁面(mian)布局都已(yi)經完成了(le),是(shi)時候(hou)調用API編寫邏輯層的(de)代(dai)碼來填充數據到頁面(mian)上了(le),在開始(shi)之前(qian)我(wo)們(men)先清(qing)理(li)一下無用的(de)代(dai)碼
打開(kai) app.js 刪掉無用的函數和屬性
App({
})
以上這步(bu)是額(e)外步(bu)驟,并(bing)不影響我(wo)們接下來要做的事情
打(da)開 utils/util.js 并清空里面的代碼,添加如下內(nei)容
// 查詢事件列表的Base URL
const API_URL_L = "//v.juhe.cn/todayOnhistory/queryEvent.php"
// 查詢詳細信息的Base URL
const API_URL_D = "//v.juhe.cn/todayOnhistory/queryDetail.php"
// 申請API獲得的KEY
const API_KEY = "YOUR API KEY"
// 獲取事件列表
function fetchEvents(today) {
var promise = new Promise(function(resolve, reject){
wx.request({
url: API_URL_L,
data: {
key: API_KEY,
date: today
},
header: {
'Content-Type': 'application/json'
},
success: resolve,
fail: reject
})
})
return promise
}
function getEvents() {
var tmpDate = new Date()
var today = tmpDate.getMonth() + 1
today = today + '/' + tmpDate.getDate()
return fetchEvents(today)
.then(function(res) {
// console.log(res.data.result)
return res.data.result
})
.catch(function(err) {
console.log(err)
return []
})
}
// 獲取詳細信息
function fetchDetail(e_id) {
var promise = new Promise(function(resolve, reject){
wx.request({
url: API_URL_D,
data: {
key: API_KEY,
e_id: e_id
},
header: {
'Content-Type': 'application/json'
},
success: resolve,
fail: reject
})
})
return promise
}
function getDetail(e_id) {
return fetchDetail(e_id)
.then(function(res) {
// console.log(res.data.result)
return res.data.result
})
.catch(function(err) {
console.log(err)
return []
})
}
module.exports = {
getEvents: getEvents,
getDetail: getDetail
}
注: 請將 API_KEY 的(de)值(zhi)替換為你申請到(dao)的(de)KEY
我們要(yao)利(li)用API獲取(qu)的(de)數據有兩(liang)種(zhong),一(yi)是「事(shi)件列表」,另一(yi)種(zhong)是事(shi)件對(dui)應的(de)「詳(xiang)細信息」,上(shang)面使用到了 ES6 原生提供的(de) Promise 對(dui)象,具體請參(can)考阮一(yi)峰的(de)《JavaScript 標(biao)準參(can)考教程(alpha)》中 「Promise對(dui)象」 一(yi)節
最后還用到了 module.exports 對外(wai)(wai)暴露兩個(ge)函數,使外(wai)(wai)部可以(yi)調用
我們繼續打開 pages/index/index.js 文件,修改成這(zhe)樣(yang)
const util = require('../../utils/util.js')
Page({
data: {
hidden: false,
events: []
},
onLoad:function(options){
// 頁面初始化 options為頁面跳轉所帶來的參數
var self = this
util.getEvents().then(function(data) {
self.setData({
hidden: true,
events: data
})
})
}
})
然(ran)后打開 pages/detail/detail.js ,修(xiu)改如下
const util = require('../../utils/util.js')
Page({
data:{
hidden: false,
detail: {}
},
onLoad:function(param){
// 頁面初始化 param為頁面跳轉所帶來的參數
var self = this
util.getDetail(param.id).then(function(result){
self.setData({
detail: result[0]
})
})
},
onReady:function(){
// 頁面渲染完成
wx.setNavigationBarTitle({
title: this.data.detail.title
})
this.setData({
hidden: true
})
}
})
這(zhe)里我們調用了 wx.setNavigationBarTitle 方(fang)法動態設置導航欄(lan)的(de)標題(ti)內容,需要注(zhu)意的(de)是(shi)必須在頁面渲染完成之后(hou),即 onReady 之后(hou)才能調用該方(fang)法修改(gai)導航欄(lan)標題(ti)
這(zhe)次教程就到這(zhe)里結(jie)束(shu)啦~涉及(ji)到的(de)(de)(de)部(bu)分知(zhi)識(shi)點并沒有詳細介(jie)紹(shao)和(he)說(shuo)明,如(ru)果有不明白的(de)(de)(de)地方請大家(jia)根(gen)據我給出的(de)(de)(de)鏈接(jie)去(qu)查看詳細的(de)(de)(de)介(jie)紹(shao),此文權當快(kuai)速上手的(de)(de)(de)一個引(yin)子,更加(jia)深入的(de)(de)(de)內容以及(ji)小程序的(de)(de)(de)其他API的(de)(de)(de)使(shi)用,還需要(yao)各位親自去(qu)實(shi)踐,歡(huan)迎交流(liu)~