看(kan)(kan)了那么多(duo)的(de)(de)小(xiao)程序入門,想必各(ge)位看(kan)(kan)官也差不多(duo)對(dui)小(xiao)程序已經有(you)了一定的(de)(de)了解(jie)。這篇文章就(jiu)不再主(zhu)講入門,現在(zai)我(wo)們要通(tong)過一個知乎日報(bao)的(de)(de)小(xiao)程序去實踐一下,加深對(dui)微信小(xiao)程序API的(de)(de)理解(jie)。
對了(le),入(ru)門(men)可(ke)以看這篇(pian)文章,里(li)面(mian)有工具的(de)初(chu)步(bu)使用介(jie)紹:
//www.jianshu.com/p/37dfcea4a2f8 微信小程序開發入門教程
//mp.weixin.qq.com/debug/wxadoc/dev/devtools/download.html 微信小程序開發工具下載
//mp.weixin.qq.com/debug/wxadoc/dev/index.html 微信小程序官方文檔
//doc.pietian.com/ 微信小程序(xu)開(kai)發文檔離線下載地址(zhi)
好了,下面我們開始(shi)吧。
首先先看看我們今天要做的知乎日報的成果。
如(ru)下圖。不過由于篇幅問題,今天只講首頁的(de)完成(cheng),里面包含了與(yu)后端的(de)交互,頁面的(de)布局,數據(ju)的(de)渲染,事件(jian)響應等,基本上囊括了如(ru)何制作一(yi)個(ge)單頁所有開發(fa)。

知乎(hu)日報-簡要版 API:
//news-at.zhihu.com/api/4/news/latest 今日熱文
//news.at.zhihu.com/api/4/news/before/ 更(geng)多往日(ri)熱文(wen)
上(shang)面這兩個地址是我們今天要做的首頁的API,我們將發起request請求,拿回數據做渲染(ran)。
下面我們將開始編寫代(dai)碼,請保持首頁(ye)目錄結(jie)構跟我下圖一致。

好,首先(xian)我們(men)先(xian)寫JS文件(jian),代碼如下,而且我都(dou)加(jia)了詳(xiang)細的(de)注釋。
// index.js
//index.js
//獲取應用實例
var app = getApp()
var utils = require('../../utils/util.js');
//初始化數據
Page({
data: {
list: [],
duration: 2000,
indicatorDots: true,
autoplay: true,
interval: 3000,
loading: false,
plain: false
},
//onLoad方法,程序啟動自執行,請求知乎日報今日熱聞接口
onLoad: function () {
var that = this;
wx.request({
url: '//news-at.zhihu.com/api/4/news/latest',
headers: { // http頭數據
'Content-Type': 'application/json'
},
success: function (res) { //請求成功后的回調
that.setData({ // 設置返回值
banner: res.data.top_stories, //banner圖片數據
list: [{ header: '今日熱聞' }].concat(res.data.stories) //熱聞數據list
})
}
})
this.index = 1; //方便下拉點擊更多時的計數下標,暫可忽略
},
//下拉滾動條,點擊更多的響應
loadMore: function (e) {
if (this.data.list.length === 0) return
var date = this.getNextDate()
var that = this
that.setData({ loading: true });
wx.request({ // 再次發起請求,請求上一天的熱聞
url: '//news.at.zhihu.com/api/4/news/before/' + (Number(utils.formatDate(date)) + 1), //此此API需要帶日期
headers: {
'Content-Type': 'application/json'
},
success: function (res) { // 成功回調
that.setData({
loading: false,
list: that.data.list.concat([{ header: utils.formatDate(date, '-') }]).concat(res.data.stories)
})
}
})
},
//事件處理函數
bindViewTap: function(e) {
wx.navigateTo({
url: '../detail/detail?id=' + e.target.dataset.id
})
},
//轉換時間函數
getNextDate: function (){
var now = new Date()
now.setDate(now.getDate() - this.index++)
return now
},
})
這里我們簡單講下(xia)幾(ji)個要點(dian):
目前微信(xin)小(xiao)程序只能支持(chi)
this.setData({....});
無法直接指定(ding)一(yi)個值
this.data.xxxx = ''; //記住,這樣是不行的。
這是頁(ye)面生命周期里(li)的一(yi)個(ge)監聽頁(ye)面加載(zai)的方法,就是說每一(yi)次進入這個(ge)頁(ye)面開始都(dou)要執行這里(li)面的方法,和JS中load一(yi)樣。
微(wei)信小程序(xu)中和后端交互(hu)也是采用的(de)請求接口(kou),具(ju)體樣(yang)例如下(xia),我已經加了注釋了,想(xiang)必都能(neng)看懂。
wx.request({
url: 'test.php', //接口地址
data: { // 參數
x: '' ,
y: ''
},
header: { // 頭信息
'Content-Type': 'application/json'
},
success: function(res) { // 成功 回調
console.log(res.data)
}
})
好了,寫完(wan)了和(he)后端交互的js代碼,這(zhe)樣我們就拿到(dao)了數(shu)據,現在我們開始(shi)寫頁面的布(bu)局。
其實(shi)微信小程(cheng)序(xu)在(zai)渲染頁(ye)面(mian)這塊,采用的也是(shi)一種模板引擎的方式。而且頁(ye)面(mian)取值方式都比較通用。和其他(ta)一些頁(ye)面(mian)模板引擎都是(shi)差不多的。
好,我們開始吧。這個(ge)頁面(mian)布局(ju)還是(shi)比較(jiao)簡單的。

首先,我們去找下文檔,會有專門的banner組件,
swiper(點擊(ji)可以(yi)跳轉文檔)
我們就用這個swiper組(zu)件(jian)寫咱們的bannner模塊,這里有個注(zhu)意點
在 swiper 組(zu)件中只可放置<swiper-item/>組(zu)件,其他(ta)節(jie)點會被自(zi)動刪(shan)除。
// index.html banner模塊代碼
<swiper indicator-dots="{{indicatorDots}}"
autoplay="{{autoplay}}" class="banners" interval="{{interval}}" duration="{{duration}}">
<!-- 循環bannner圖片開始-->
<block wx:for="{{banner}}">
<swiper-item class="banner" >
<image src="{{item.image}}" data-id="{{item.id}}" bindtap="bindViewTap" class="banner-image" width="100%" height="100%"/>
<text class="banner-title">{{item.title}}</text>
</swiper-item>
</block>
<!-- 循環bannner圖片結束-->
</swiper>
其實下面的一個熱聞列表也就是一個list循環,這邊怎么做循環呢,同樣我們可以查詢API文檔可得。
利用(yong) wx-for 屬(shu)(shu)性(xing),但是這(zhe)只是一(yi)(yi)個(ge)(ge)屬(shu)(shu)性(xing),我們需(xu)要把它加(jia)到一(yi)(yi)個(ge)(ge)標簽(qian)上面才能執行(xing),為了(le)承載這(zhe)個(ge)(ge)屬(shu)(shu)性(xing),微信小程序專門定義了(le)一(yi)(yi)個(ge)(ge)無其他作(zuo)用(yong)的(de)標簽(qian) <block>。
另外注意,微(wei)信小程序里(li)有(you)很(hen)多默(mo)認(ren):
在組(zu)(zu)(zu)件上使(shi)用wx:for控制(zhi)屬(shu)性綁(bang)定一個(ge)數(shu)組(zu)(zu)(zu),即可使(shi)用數(shu)組(zu)(zu)(zu)中各項的(de)數(shu)據重復渲(xuan)染該組(zu)(zu)(zu)件。默認數(shu)組(zu)(zu)(zu)的(de)當(dang)前(qian)項的(de)下標變量(liang)名(ming)默認為index,數(shu)組(zu)(zu)(zu)當(dang)前(qian)項的(de)變量(liang)名(ming)默認為item,如果(guo)需要修改(gai)的(de)話,使(shi)用 wx:for-item 可以(yi)指定數(shu)組(zu)(zu)(zu)當(dang)前(qian)元素(su)的(de)變量(liang)名(ming)。
所以對下面(mian)的item.header不(bu)要驚(jing)訝(ya),item哪(na)來的。
代碼如下:
<view class="news-item-container">
<block wx:for="{{list}}" wx:for-index="id">
<text wx:if="{{item.header}}" class="sub-title">{{item.header}}</text>
<navigator wx:else url="../detail/detail?id={{item.id}}">
<view class="news-item" >
<view class="news-item-left">
<text class="news-item-title">{{item.title}}</text>
</view>
<view class="news-item-right">
<image src="{{item.images[0]}}" class="news-image"/>
</view>
</view>
</navigator>
</block>
<button type="primary" class="load-btn" size="mini" loading="{{loading}}" plain="{{plain}}" bindtap="loadMore"> 更多 </button>
</view>
另外,這里有個更多的(de)點擊(ji)響應,使用的(de)是 bindtap 屬性指定響應方(fang)法名(ming)。
這個就不(bu)單獨說了,跟平(ping)時(shi)寫的 css幾(ji)乎沒啥區別。最后也會放出源(yuan)代碼給大(da)家下載。
這篇小文,只是帶領大家做一個和服務端進行交互的小demo,加深下對微信小程序的前前后后的理解。
后續的正在coding中....
敬請期待。