從零開始帶你擼一個小程序
微信推出小程序已經有些天了,相信同學們或多或少都把玩體驗過小程序了。今天從零學習前端開發專欄就手把手帶你,從零開始擼一個小程序。
P.S.正式開始前先聲明,本教程示例僅供前端萌新學習體驗,閑雜人等可以退散啦。
小程序的註冊(可跳過)
小程序是面向企業、政府、媒體等其他組織開放註冊的,註冊時必須提供相應的主體信息,所以假如你是不代表任何組織沒註冊過任何公司的獨立開發者,就可以直接跳過這一步啦,雖然不註冊就很遺憾的不能在真機體驗調試自己寫的小程序,不過最重要的是學習知識不是么?
給有條件的同學的傳送門:小程序註冊圖文教程
如果你之前有玩過微信公眾號的話,註冊和配置流程其實都大同小異。
小程序本地開發環境搭建
小程序使用微信Web開發者工具作為IDE。微信Web開發者工具是微信官方使用NW.js開發的一個跨平台桌面端應用,好壞先不做評價,至少能用。雖然現在小程序已經有了一些第三方的開發工具,有更多Hack以及更少的限制,但為了教程的簡潔這裡就不再贅述,有興趣的同學可以自己去玩玩看。
微信Web開發者工具下載
第三方小程序開發工具
- Egret Wing 3.2.x 支持微信小程序實時預覽的IDE)
- WEPT 一個微信小程序實時運行環境
微信Web開發者工具的安裝更是簡單,不停點下一步就好了。
創建小程序項目
按照微信官方簡易教程的指引,創建一個新的小程序項目。
我們需要打開微信Web開發者工具,掃碼登陸,選擇開發本地小程序,然後點擊新建項目,填入你的小程序AppID,項目名稱,目錄等等。
其實不管你有沒有註冊小程序,為了方便調試最好都選擇無AppID,如果選擇無AppID一些API的返回都是本地模擬的,並且沒有請求遠程伺服器的域名限制,反而方便你開發調試。
創建項目的時候我們可以勾選創建quick start項目,來當作我們編寫代碼的模板,其實這個quick start項目的代碼就是微信官方的簡易教程中的示例代碼,當然如果你有心的話,也可以手動跟著教程把代碼敲一遍。
開發者工具簡介
創建好項目並打開之後,我們會看到一個類似或者其實根本就是Chrome打開開發者工具並啟用移動端模擬的界面。
左邊有3個選項卡【編輯】【調試】【項目】,開發的過程中大多數時間裡我們都是在【編輯】【調試】之間來回切。
切換到【編輯】選項卡,我們就能看到小程序項目目錄以及代碼編輯界面。
小程序示例開發
接下來我們會在quick start項目代碼的基礎上開發一個獲取用戶位置並顯示天氣的小程序,一邊學習理解小程序的框架設計,一邊嘗試動手編寫代碼。
首先每一個小程序都需要聲明一個App對象:
//app.jsApp({ onLaunch: function () { //調用API從本地緩存中獲取數據 var logs = wx.getStorageSync("logs") || [] logs.unshift(Date.now()) wx.setStorageSync("logs", logs) }, getUserInfo:function(cb){ var that = this; if(this.globalData.userInfo){ typeof cb == "function" && cb(this.globalData.userInfo) }else{ //調用登錄介面 wx.login({ success: function () { wx.getUserInfo({ success: function (res) { that.globalData.userInfo = res.userInfo; typeof cb == "function" && cb(that.globalData.userInfo) } }) } }); } }, globalData:{ userInfo:null }})
假如你之前了解過React/Vue任意一個框架的話,應該會看到很多他們的影子:
//Reactclass Timer extends React.Component { constructor(props) { super(props); this.state = { secondsElapsed: 0 }; } tick() { this.setState(prevState => ({ secondsElapsed: prevState.secondsElapsed + 1 })); } componentDidMount() { this.interval = setInterval(() => this.tick(), 1000); } componentWillUnmount() { clearInterval(this.interval); } render() { return React.createElement( "div", null, "Seconds Elapsed: ", this.state.secondsElapsed ); }}//Vuevar vm = new Vue({ data: { a: 1 }, created: function () { // `this` 指向 vm 實例 console.log("a is: " + this.a) }, mounted: function () { console.log("mounted!") }, updated: function () { console.log("updated!") }, destroyed: function () { console.log("destroyed!") }})
每一個小程序都會有一個app.json的配置文件,這裡面其實有很多好玩的地方:
{ "pages":[//小程序包含的頁面 "pages/index/index",//頁面路徑 "pages/logs/logs" ], "window":{ "backgroundTextStyle":"light", "navigationBarBackgroundColor": "#2f3b53",//標題欄背景色(這也許是小程序和移動端Web應用最大的不同了) "navigationBarTitleText": "Weather",//標題欄文字 "navigationBarTextStyle":"white"//標題欄文字顏色 }, "tabBar": {//配置小程序選項卡,是的,你不需要寫多餘的導航欄代碼,只需要配置一段JSON即可 "selectedColor":"#73d0f4", //Tab欄選中文字的顏色 "list": [{//選項卡列表,最多可以配置5項 "pagePath": "pages/index/index",//對應頁面地址 "iconPath": "assets/images/home_n.png",//Tab選項卡默認圖標 "selectedIconPath": "assets/images/home.png",//Tab選中後的圖標 "text": "首頁"//Tab文字 }, { "pagePath": "pages/logs/logs", "iconPath": "assets/images/box_n.png", "selectedIconPath": "assets/images/box.png", "text": "日誌" }] }}
你可以在quick start項目的基礎上把app.json文件修改成如上內容,當然你也可以參考官方配置文檔自己折騰一會兒。
另外補充一下,Tab欄的圖標當然不是憑空變出來的,你可以在easyicon或者其他類似的網站下載你需要的圖標,具體風格可以參考微信底部導航,需要注意的是你要為每個圖標準備兩個文件,一個默認顯示,一個在選中時顯示。
製作這樣圖標文件的最簡單辦法是在PS中打開圖標文件,選擇圖像->調整->去色並另存為。
小程序頁面
小程序的所有頁面一般都被保存在pages文件夾里,每一個獨立的頁面也有自己的文件夾,每個頁面都包含自己的js/json/wxml/wxss文件,不管每個文件里有沒有內容,你創建的頁面只要一次調試編譯之後這四個文件都會自動生成。
.js和.json文件可以延伸剛剛介紹過的app.js/app.json文件的概念,頁面的這兩個文件分別儲存每個獨立頁面的邏輯和配置信息。
.wxml可以理解為.html的閹割版,用來編寫小程序頁面的內容。
.wxss可以理解為.css的閹割版,用來設計小程序頁面的樣式。
接下來我們再動手寫幾行代碼,首先把pages/index/index.wxml改寫成如下內容:
<!--index.wxml--><!--view是wxml中最基本的一種視圖容器,你可以把它理解為div一類的東西--><view class="container"> <!--bindtap類似於vue里的v-on:click,用於處理頁面元素的事件綁定,待會兒我們會在index.js里看到一個bindViewTap的方法--> <view bindtap="bindViewTap" class="userinfo"> <!--{{userInfo.avatarUrl}}這類的雙花括弧和vue簡直是一模一樣了,用來顯示js中的變數,當然也可以包含一些簡單的運算和邏輯判斷,image你就理解為img標籤好了--> <image class="userinfo-avatar" src="{{userInfo.avatarUrl}}" background-size="cover"></image> <!--text可以理解為p標籤,當然只是為了方便理解,上述所有的view/image/text等都是小程序預置的界面組件--> <text class="userinfo-nickname">{{userInfo.nickName}}</text> </view> <!--wx:if完全可以理解為vue當中的v-if,哈哈,其實不如去學學vue吧,weather是一個對象變數,可以用點來訪問其屬性值--> <view wx:if="{{weather.location}}" class="weather"> <text class="city">{{weather.location.name}}</text> <text class="condition">{{weather.now.text}}</text> <text class="temp">{{weather.now.temperature}} ℃</text> </view></view>
接下來在index.wxss的底部添加下列內容,我承認我偷懶了,你可以稍微花點功夫認真設計一下你小程序的外觀樣式:
.weather { margin-top: 50px; display: flex; flex-direction: column;}.city,.condition,.temp { width:100%; margin-top: 10px;}
wxss支持不完全的css選擇器,引入了名為rpx的尺寸單位等,有關wxss具體可以查看wxss文檔
最後到了重頭戲,讓我們打開index.js,將其改寫為如下內容:
//index.js//獲取應用實例var app = getApp()Page({ data: { userInfo: {}, //這裡新增了一個weather變數 weather: {} }, //事件處理函數,這就是剛剛在index.wxml當中綁定的事件函數 bindViewTap: function() { //將函數的內容改寫為我們自定義的一個方法 this.getLocation() }, //這個自定義方法調用了wx.getLocation和wx.request兩個小程序API,用來獲取用戶位置信息並從遠程伺服器請求相關天氣數據 getLocation: function () { //示例中有很多這樣that = this的代碼,但我發現最新的開發者工具是支持ES6的,你完全可以用autobinding一類的語法糖來避免這些冗餘的綁定代碼 var that = this //這是小程序的一個API,用來獲取用戶的地理位置 wx.getLocation({ type: "wgs84", success: function(res) { var latitude = res.latitude var longitude = res.longitude //wx.request用來發起向遠程伺服器的請求 wx.request({ //wx.request訪問的遠程網址必須是https,這裡使用的是很棒的心知天氣的API,可以免費註冊 url: "https://api.thinkpage.cn/v3/weather/now.json?key=xxxxxxxxxxx&location="+latitude+":"+longitude, success: function(res) { console.log(res.data.results[0]) //setData方法可以理解為React當中的setState方法,用來修改我們在開頭定義的weather變數,你不能直接通過data.weather來修改,那樣的操作會破壞數據綁定 that.setData({ weather:res.data.results[0] }) } }) } }) }, //onLoad是頁面的一個生命周期函數,類似於App對象中的,小程序的頁面和應用對象都有一系列相關的生命周期函數 onLoad: function () { console.log("onLoad") //這裡再啰嗦一下,因為對象中的方法this默認指向undefined,所以我們需要手動指定this,這段代碼還可以寫成: /** * app.getUserInfo(function(userInfo){ * //更新數據 * this.setData({ * userInfo:userInfo * }) * }.bind(this)) * 或者使用es6寫成: * app.getUserInfo((userInfo) => { * this.setData({ * userInfo:userInfo * }) * }) */ var that = this //調用應用實例的方法獲取全局數據 app.getUserInfo(function(userInfo){ //更新數據 that.setData({ userInfo:userInfo }) }) //that.getLocation() }})
示例中使用的API來自心知天氣,你可以免費註冊並將API地址中的key=xxxxxxxxxxx替換為你自己的key.
另外要注意的一點是,如果你註冊並填寫了小程序的AppID,還需要在小程序的設置中填寫request請求的合法域名,否則在調試時會報錯,而沒有填寫AppID的小程序則不受這個限制。
之後記得保存所有的文件,刷新小程序頁面,我們的天氣示例小程序就大功告成啦,現在點擊你的微信頭像,就可以獲取你所在地區的天氣信息啦。
如果你註冊了小程序,還可以切換到【項目】選項卡,點擊預覽並通過微信掃碼進行真機調試:
到這裡我們的教程就告一段落啦,如果你對小程序很感興趣,可以自己進行更深入的嘗試和學習,還有很多在普通網頁中無法訪問的有意思的API可以玩。
本教程示例代碼:discountry/weapp-weather
更多有關小程序的資源請訪問:微信小程序開發資源匯總
而我個人以為學小程序還不如學學React或者Vue,又或者踏踏實實地學編程。
風頭過後,小程序離改變世界還有著遙不可及的距離。
有任何好的建議或意見以及對小程序的任何觀點看法歡迎在評論區參與討論。
推薦閱讀: