上周微信小程序公測了,允許開發(fā)者將應用提交到微信公眾平臺審核,但暫時還不能發(fā)布。
微信小程序是不用下載即能使用的應用,它相比原生app更新實時、跨平臺、開發(fā)成本低、使用門檻低,一經(jīng)宣布,便受到業(yè)內(nèi)的強烈關注。最近動手嘗試了下微信小程序。
這篇文章將繼續(xù)以iOS開發(fā)的視角介紹微信小程序的開發(fā)心得。
首先介紹一下小程序的結(jié)構目錄:
按官方文檔的說明,app.js用于處理小程序邏輯,用于監(jiān)聽小程序的生命周期、聲明全局變量。app.wxss用于管理小程序公共樣式,app.json文件用來對微信小程序進行全局配置,決定頁面文件的路徑、窗口表現(xiàn)、設置網(wǎng)絡超時時間、設置多 tab 等。在iOS中,相當于AppDelegate類。
如下所示,pages設置頁面路徑,window設置默認頁面的窗口表現(xiàn),tabbar設置底部 tab 的表現(xiàn),networkTimeout設置網(wǎng)絡超時時間,debug設置是否開啟 debug 模式。
{ "pages": [ "pages/index/index", "pages/logs/index" ], "window": { "navigationBarTitleText": "Demo" }, "tabBar": { "list": [{ "pagePath": "pages/index/index", "text": "首頁" }, { "pagePath": "pages/logs/logs", "text": "日志" }] }, "networkTimeout": { "request": 10000, "downloadFile": 10000 }, "debug": true }
每個頁面又是由.js、.wxml、.wxss、.json文件構成,.js是頁面邏輯,.wxml處理頁面結(jié)構,.wxss處理頁面樣式,.json處理頁面配置。
小程序的生命周期如下圖
在iOS中,onLaunch方法類似于application:didFinishLaunchingWithOptions:,onHide類似于applicationDidEnterBackground:,onShow類似于applicationWillEnterForeground:
頁面的生命周期如下
onLoad相當于loadView,onReady相當于viewDidLoad,onShow相當于viewDidApear:,onUnload相當于viewDidDisappear:。與iOS不同的是,小程序先調(diào)用onShow方法再調(diào)用onReady,onHide表示頁面隱藏,當navigateTo或底部tab切換時調(diào)用。
小程序的頁面中轉(zhuǎn)比較簡單,主要有三個方法:
wx.navigateTo(OBJECT):保留當前頁面,跳轉(zhuǎn)到應用內(nèi)的某個頁面,使用wx.navigateBack可以返回到原頁面。相當于iOS中的push跳轉(zhuǎn)。
wx.redirectTo(OBJECT):關閉當前頁面,跳轉(zhuǎn)到應用內(nèi)的某個頁面。
wx.navigateBack():關閉當前頁面,回退前一頁面。相當于iOS中的pop返回。
小程序有一套UI與數(shù)據(jù)的綁定機制,有點類似MVVM模式,它是單向綁定的,只能從Data更新到View,而且要手動調(diào)用setData方法才能更新view。
語法類似這樣,在.wxml文件中用雙大括號將變量包起來,在.js文件中修改數(shù)據(jù),調(diào)用setData方法,UI根據(jù)這個數(shù)據(jù)的最新結(jié)果刷新。
//page.wxml <view> {{ message }} </view> //page.js Page({ data: { message: '' }, onLoad: function(options) { this.setData({ message:'Hello world' }) } })
小程序的數(shù)據(jù)綁定還支持表達式,如條件表達式、算術表達式、字符串表達式、三元表達式。
//用 wx:if="{{condition}}" 來判斷是否需要渲染該代碼塊: <view wx:if="{{condition}}"> True </view> //wx:for控制屬性綁定一個數(shù)組,即可使用數(shù)組中各項的數(shù)據(jù)重復渲染該組件。 <view wx:for="{{array}}"> {{index}}: {{item.message}} </view>
接下來我們一起寫一個小程序demo。效果如下:
首先創(chuàng)建項目,設置項目名稱,選擇項目位置,這里選擇了無Appid
創(chuàng)建兩個頁面,一個主頁index和一個詳情頁book
在app.json文件中對app進行配置,在pages屬性中,添加文件路徑,路徑是相對位置。在window屬性中,設置窗體的顏色、標題等。
{ "pages":[ "pages/index/index", "pages/book/book" ], "window":{ "navigationBarBackgroundColor": "#ffffff", "navigationBarTextStyle": "black", "navigationBarTitleText": "豆瓣科幻小說", "backgroundColor": "#eeeeee", "backgroundTextStyle": "light" }, "tabBar": { "color":"#030303", "selectedColor":"#111", "backgroundColor":"#fff", "borderStyle":"black", "list":[{"pagePath":"pages/index/index", "text":"首頁"}, {"pagePath":"pages/index/me", "text":"我"}] }, "networkTimeout":{ "request":10000, "downloadFile":10000 }, "debug":true }
我們從豆瓣api中獲取科幻小說列表數(shù)據(jù),不像iOS取數(shù)據(jù)那么麻煩,小程序提供了簡單的api進行網(wǎng)絡通信,而且也不用建立model,取到的數(shù)據(jù)直接使用??词醉摯a,data內(nèi)的幾個鍵值對相當于變量初始化,如books表示存放書籍的數(shù)組,當onLoad頁面加載完成后向網(wǎng)絡請求數(shù)據(jù),這里獲取科幻小說列表,拿到數(shù)據(jù)后調(diào)用setData更新當前頁面。
var app = getApp() var API_URL = "https://api.douban.com/v2/book/search" Page({ data: { size: 100, title: "數(shù)據(jù)加載中...", books: [], loading: true }, onLoad: function() { var _this = this console.log(_this.data) var params = { tag: "科幻", start: 0, count: _this.data.size } wx.request({ url: API_URL, data: params, method: 'GET', // OPTIONS, GET, HEAD, POST, PUT, DELETE, TRACE, CONNECT header: {"Content-Type":"application/json"}, success: function(res){ // success _this.setData({ books: res.data.books, loading: false }) }, fail: function() { // fail }, complete: function() { // complete } }) }, })
在index.wxml中,放置加載動畫loading和滾動組件scroll-view,加載動畫綁定了loading屬性,決定是否顯示或隱藏。navigator表示點擊即重定向到書籍詳情頁,相當于push到詳情頁。\<view class="item"\>相當于cell,cell內(nèi)的每個控件都綁定book,當books更新時,刷新UI。
<loading hidden="{{!loading}}"> {{title}} </loading> <scroll-view scroll-y="true" class="page-body" > <navigator url="../book/book?id={{item.id}}" wx:for="{{books}}"> <view class="item"> <image class="poster" src="{{item.images.small}}"></image> <view class="meta"> <text class="title">{{item.title}}</text> <view class="author"> <text wx:for="{{item.author}}">{{item}}</text> </view> <text class="subtitle">{{item.publisher}} / {{item.pubdate}}</text> </view> <view class="rating"> <text>{{item.rating.average}}</text> </view> </view> </navigator> </scroll-view>
index.wxss是樣式表文件,控制首頁的布局和樣式。css布局不熟悉,跟iOS差別還是比較大的,需要多寫一些。
page { font-family: -apple-system-font, 'Helvetica Neue', Helvetica, 'Microsoft YaHei', sans-serif; font-family:; background-color: #fff; display: flex; flex-direction: column; } .page-header { display: flex; justify-content: center; border-bottom: 1rpx solid #ccc; } .page-header-text { padding: 20rpx 40rpx; color: #999; font-size: 38rpx; text-align: center; } .page-body { display: flex; flex: 1; flex-direction: column; height: 100%; } .item { display: flex; padding: 20rpx 40rpx; border-bottom: 1rpx solid #eee; cursor: pointer; } .item .poster { width: 128rpx; height: 128rpx; margin-right: 20rpx; } .item .meta { flex: 1; } .item .meta .title, .item .meta .sub-title { display: block; margin-bottom: 15rpx; } .item .meta .title { font-size: 32rpx; } .item .meta .sub-title { font-size: 22rpx; color: #c0c0c0; } .item .meta .subtitle { font-size: 26rpx; color: #999; } .item .meta .author { font-size: 26rpx; color: #999; } .item .rating { font-size: 28rpx; font-weight: bold; color: #f74c31; } .tips { font-size: 28rpx; text-align: center; padding: 50rpx; color: #ccc; } .tips image { width: 40rpx; height: 40rpx; margin-right: 20rpx; } .tips image, .tips text { vertical-align: middle; }
書籍詳情頁跟列表頁比較類似,也更簡單,就不貼代碼了,具體看demo,demo已上傳github:https://github.com/superzcj/DouBanNovelDemo
在iOS開發(fā)中,MVVM其實很少用的,不過寫了這個小程序demo,發(fā)現(xiàn)MVVM還是挺棒的,代碼寫的更簡潔、優(yōu)雅。小程序比較輕量,相對iOS開發(fā)還是挺簡單的,很多功能都被封裝,比如tabbar的配置、網(wǎng)絡api的使用以及json的直接使用,這樣開發(fā)就更簡單,更容易快速出產(chǎn)品。
作為一個iOS開發(fā),對前端開發(fā)不熟悉,文章中難免有錯誤有不足,希望大家多多指正。
如果覺得我的這篇文章對你有幫助,請在下方點個贊支持一下,謝謝!