小程序
1 創(chuàng)建項目
- 我們需要通過開發(fā)者工具胯盯,來完成小程序創(chuàng)建和代碼編輯懈费。
- 開發(fā)者工具安裝完成后,打開并使用微信掃碼登錄博脑。選擇創(chuàng)建“項目”憎乙,填入上文獲取到的 AppID 票罐,設置一個本地項目的名稱(非小程序名稱),比如“我的第一個項目”泞边,并選擇一個本地的文件夾作為代碼存儲的目錄该押,點擊“新建項目”就可以了。
- 為方便初學者了解微信小程序的基本代碼結(jié)構(gòu)繁堡,在創(chuàng)建過程中沈善,如果選擇的本地文件夾是個空文件夾,開發(fā)者工具會提示椭蹄,是否需要創(chuàng)建一個 quick start 項目。選擇“是”净赴,開發(fā)者工具會幫助我們在開發(fā)目錄里生成一個簡單的 demo绳矩。
2 代碼編寫
- 點擊開發(fā)者工具左側(cè)導航的“編輯”,我們可以看到這個項目玖翅,已經(jīng)初始化并包含了一些簡單的代碼文件翼馆。最關鍵也是必不可少的,是 app.js金度、app.json应媚、app.wxss 這三個。其中猜极,.js后綴的是腳本文件中姜,.json后綴的文件是配置文件,.wxss后綴的是樣式表文件跟伏。微信小程序會讀取這些文件丢胚,并生成小程序?qū)嵗?/li>
- app.js是小程序的腳本代碼。我們可以在這個文件中監(jiān)聽并處理小程序的生命周期函數(shù)受扳、聲明全局變量携龟。調(diào)用框架提供的豐富的 API,如本例的同步存儲及同步讀取本地數(shù)據(jù)勘高。想了解更多可用 API峡蟋,可參考 API 文檔。
//app.js
App({
onLaunch: function () {
//調(diào)用API從本地緩存中獲取數(shù)據(jù)
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{
//調(diào)用登錄接口
wx.login({
success: function () {
wx.getUserInfo({
success: function (res) {
that.globalData.userInfo = res.userInfo;
typeof cb == "function" && cb(that.globalData.userInfo)
}
})
}
});
}
},
globalData:{
userInfo:null
}
})
- app.json 是對整個小程序的全局配置华望。我們可以在這個文件中配置小程序是由哪些頁面組成蕊蝗,配置小程序的窗口背景色,配置導航條樣式立美,配置默認標題匿又。注意該文件不可添加任何注釋。更多可配置項可參考配置詳解建蹄。
{
"pages":[
"pages/index/index",
"pages/logs/logs"
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "WeChat",
"navigationBarTextStyle":"black"
}
}
- app.wxss 是整個小程序的公共樣式表碌更。我們可以在頁面組件的 class 屬性上直接使用 app.wxss 中聲明的樣式規(guī)則裕偿。
/**app.wxss**/
.container {
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-between;
padding: 200rpx 0;
box-sizing: border-box;
}
- 每一個小程序頁面是由同路徑下同名的四個不同后綴文件的組成,如:index.js痛单、index.wxml嘿棘、index.wxss、index.json旭绒。.js后綴的文件是腳本文件鸟妙,.json后綴的文件是配置文件,.wxss后綴的是樣式表文件挥吵,.wxml后綴的文件是頁面結(jié)構(gòu)文件
3 項目目錄
|- components 組件目錄
|- assets 靜態(tài)資源目錄
|- images
... ...
|- pages 小程序頁面
|- index
|- index.js
|- index.json
|- index.wxml
|- index.wxss
|- login
|- login.js
|- login.json
|- login.wxml
|- login.wxss
......
|- utils 公共方法目錄
|- util.js
......
|- app.js 小程序主入口
|- app.json 全局配置文件
|- app.wxss 全局樣式文件
4 生命周期
4.1 App
- App() 函數(shù)用來注冊一個小程序重父。接受一個 object 參數(shù),其指定小程序的生命周期函數(shù)等忽匈。
App({
onLaunch: function(options) {
// Do something initial when launch.
},
onShow: function(options) {
// Do something when show.
},
onHide: function() {
// Do something when hide.
},
onError: function(msg) {
console.log(msg)
},
globalData: 'I am global data'
})
- getApp()
- 我們提供了全局的 getApp() 函數(shù)房午,可以獲取到小程序?qū)嵗?/li>
// other.js
var appInstance = getApp()
console.log(appInstance.globalData) // I am global data
注意:
App() 必須在 app.js 中注冊,且不能注冊多個丹允。
不要在定義于 App() 內(nèi)的函數(shù)中調(diào)用 getApp() 郭厌,使用 this 就可以拿到 app 實例。
不要在 onLaunch 的時候調(diào)用 getCurrentPage()雕蔽,此時 page 還沒有生成折柠。
通過 getApp() 獲取實例之后,不要私自調(diào)用生命周期函數(shù)批狐。
4.2 Page
- Page() 函數(shù)用來注冊一個頁面扇售。接受一個 object 參數(shù),其指定頁面的初始數(shù)據(jù)贾陷、生命周期函數(shù)缘眶、事件處理函數(shù)等。
Page({
data: {
text: "This is page data."
},
onLoad: function(options) {
// Do some initialize when page load.
},
onReady: function() {
// Do something when page ready.
},
onShow: function() {
// Do something when page show.
},
onHide: function() {
// Do something when page hide.
},
onUnload: function() {
// Do something when page close.
},
onPullDownRefresh: function() {
// Do something when pull down.
},
onReachBottom: function() {
// Do something when page reach bottom.
},
onShareAppMessage: function () {
// return custom share data when user share.
},
// Event handler.
viewTap: function() {
this.setData({
text: 'Set some data for updating view.'
})
},
customData: {
hi: 'MINA'
}
})
生命周期函數(shù)
- onLoad: 頁面加載
- 一個頁面只會調(diào)用一次髓废,可以在 onLoad 中獲取打開當前頁面所調(diào)用的 query 參數(shù)巷懈。
- onShow: 頁面顯示
- 每次打開頁面都會調(diào)用一次。
- onReady: 頁面初次渲染完成
- 一個頁面只會調(diào)用一次慌洪,代表頁面已經(jīng)準備妥當顶燕,可以和視圖層進行交互。
- 對界面的設置如wx.setNavigationBarTitle請在onReady之后設置冈爹。詳見生命周期
- onHide: 頁面隱藏
- 當navigateTo或底部tab切換時調(diào)用涌攻。
- onUnload: 頁面卸載
- 當redirectTo或navigateBack的時候調(diào)用。
頁面相關事件處理函數(shù)
- onPullDownRefresh: 下拉刷新
- 監(jiān)聽用戶下拉刷新事件恳谎。
- 需要在config的window選項中開啟enablePullDownRefresh。
- 當處理完數(shù)據(jù)刷新后,wx.stopPullDownRefresh可以停止當前頁面的下拉刷新因痛。
- onShareAppMessage: 用戶分享
- 只有定義了此事件處理函數(shù)婚苹,右上角菜單才會顯示“分享”按鈕
- 用戶點擊分享按鈕的時候會調(diào)用
- 此事件需要 return 一個 Object,用于自定義分享內(nèi)容
Page({
onShareAppMessage: function () {
return {
title: '自定義分享標題',
path: '/page/user?id=123'
}
}
})
5 路由跳轉(zhuǎn)
- wx.navigateTo(OBJECT)
wx.navigateTo({
url: 'test?id=1'
})
Page({
onLoad: function(option){
console.log(option)
}
})
wx.redirectTo(OBJECT)
關閉當前頁面鸵膏,跳轉(zhuǎn)到應用內(nèi)的某個頁面膊升。wx.reLaunch(OBJECT)
關閉所有頁面,打開到應用內(nèi)的某個頁面谭企。wx.switchTab(OBJECT)
跳轉(zhuǎn)到 tabBar 頁面廓译,并關閉其他所有非 tabBar 頁面
{
"tabBar": {
"list": [{
"pagePath": "index",
"text": "首頁"
},{
"pagePath": "other",
"text": "其他"
}]
}
}
wx.switchTab({
url: '/index'
})
- wx.navigateBack(OBJECT)
關閉當前頁面,返回上一頁面或多級頁面债查》乔可通過 getCurrentPages()) 獲取當前的頁面棧,決定需要返回幾層攀操。
// 注意:調(diào)用 navigateTo 跳轉(zhuǎn)時院仿,調(diào)用該方法的頁面會被加入堆棧,而 redirectTo 方法則不會速和。見下方示例代碼
// 此處是A頁面
wx.navigateTo({
url: 'B?id=1'
})
// 此處是B頁面
wx.navigateTo({
url: 'C?id=1'
})
// 在C頁面內(nèi) navigateBack,將返回A頁面
wx.navigateBack({
delta: 2
})
tip: wx.navigateTo 和 wx.redirectTo 不允許跳轉(zhuǎn)到 tabbar 頁面剥汤,只能用 wx.switchTab 跳轉(zhuǎn)到 tabbar 頁面
6 發(fā)起請求
- wx.request(OBJECT)
wx.request發(fā)起的是 HTTPS 請求颠放。
wx.request({
url: 'test.php', //僅為示例,并非真實的接口地址
data: {
x: '' ,
y: ''
},
header: {
'content-type': 'application/json'
},
success: function(res) {
console.log(res.data)
}
})
- tip: content-type 默認為 'application/json'
- bug: 開發(fā)者工具 0.10.102800 版本吭敢,header 的 content-type 設置異常碰凶;
- tip: 客戶端的 HTTPS TLS 版本為1.2,但 Android 的部分機型還未支持 TLS 1.2鹿驼,所以請確保 HTTPS 服務器的 TLS 版本支持1.2及以下版本欲低;
- tip: 要注意 method 的 value 必須為大寫(例如:GET);
- tip: url 中不能有端口畜晰;
- tip: request 的默認超時時間和最大超時時間都是 60s
- tip: request 的最大并發(fā)數(shù)是 5
- tip: 網(wǎng)絡請求的 referer 是不可以設置的砾莱,格式固定為 https://servicewechat.com/{appid}/{version}/page-frame.html,其中 {appid} 為小程序的 appid凄鼻,{version} 為小程序的版本號腊瑟,版本號為 0 表示為開發(fā)版。
7 WXSS
- rpx(responsive pixel): 可以根據(jù)屏幕寬度進行自適應块蚌。規(guī)定屏幕寬為750rpx闰非。如在 iPhone6 上,屏幕寬度為375px峭范,共有750個物理像素财松,則750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素纱控。
8 模板
-
WXML提供模板(template)辆毡,可以在模板中定義代碼片段菜秦,然后在不同的地方調(diào)用。
定義模板
使用name屬性胚迫,作為模板的名字喷户。然后在 < template/>內(nèi)定義代碼片段
<template name="postItem">
<view class="post-container">
<view class="post-author-date">
<image class="post-author" src="{{avatar}}"></image>
<text class="post-date">{{date}}</text>
</view>
<text class="post-title">{{title}}</text>
<image class="post-image" src="{{imgSrc}}"></image>
<text class="post-content">{{content}}
</text>
<view class="post-like">
<image class="post-like-image" src="/images/icon/chat.png"></image>
<text class="post-like-font">{{collection}}</text>
<image class="post-like-image" src="/images/icon/view.png"></image>
<text class="post-like-font">{{reading}}</text>
</view>
</view>
</template>
使用模板
- 使用 is 屬性,聲明需要的使用的模板访锻,然后將模板所需要的 data 傳入褪尝。
<import src="post-item/post-item-template.wxml" />
<template is="postItem" data="{{...item}}" />
item 是模板所需要的數(shù)據(jù)。模板中不能寫js期犬,只是數(shù)據(jù)展示河哑。
9 配置
- 我們使用app.json文件來對微信小程序進行全局配置,決定頁面文件的路徑龟虎、窗口表現(xiàn)璃谨、設置網(wǎng)絡超時時間、設置多 tab 等鲤妥。
{
"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
}
pages
- 接受一個數(shù)組佳吞,每一項都是字符串,來指定小程序由哪些頁面組成棉安。每一項代表對應頁面的【路徑+文件名】信息底扳,數(shù)組的第一項代表小程序的初始頁面。小程序中新增/減少頁面贡耽,都需要對 pages 數(shù)組進行修改衷模。
window
- 用于設置小程序的狀態(tài)欄、導航條蒲赂、標題阱冶、窗口背景色。
tabBar
- 如果我們的小程序是一個多 tab 應用(客戶端窗口的底部或頂部有 tab 欄可以切換頁面)滥嘴,那么我們可以通過 tabBar 配置項指定 tab 欄的表現(xiàn)木蹬,以及 tab 切換時顯示的對應頁面。
Tip: 通過頁面跳轉(zhuǎn)(wx.navigateTo)或者頁面重定向(wx.redirectTo)所到達的頁面氏涩,即使它是定義在 tabBar 配置中的頁面届囚,也不會顯示底部的 tab 欄。
tabBar 是一個數(shù)組是尖,只能配置最少2個意系、最多5個 tab,tab 按數(shù)組的順序排序饺汹。
tabBar的樣式是固定的蛔添。上邊為圖標,下邊為文字說明。
10 常用組件
11 搜索小程序
- 小程序又增新流量入口夸溶,支持自定義關鍵詞搜索。6月3日凌晨3點多凶硅,微信小程序后臺新增推廣功能缝裁,支持開發(fā)者添加與業(yè)務相關的自定義關鍵詞,搜索策略將于6月9日正式生效足绅。開發(fā)者可在小程序后臺的 “推廣” 模塊中捷绑,配置與小程序業(yè)務相關的關鍵詞
值得注意的是,小程序可配置最多10個與業(yè)務相關的關鍵詞氢妈,關鍵詞在審核通過后粹污,會和小程序的服務質(zhì)量、用戶使用情況等因素首量,共同影響搜索結(jié)果壮吩。每30天可以修改3次。
關鍵詞設置 可配置最多10個與業(yè)務相關的關鍵詞加缘,關鍵詞在審核通過后鸭叙,會和小程序的服務質(zhì)量、用戶使用情況等因素拣宏,共同影響搜索結(jié)果递雀。
12 wx.login(OBJECT)
- 調(diào)用接口獲取登錄憑證(code)進而換取用戶登錄態(tài)信息,包括用戶的唯一標識(openid) 及本次登錄的 會話密鑰(session_key)蚀浆。用戶數(shù)據(jù)的加解密通訊需要依賴會話密鑰完成。
//app.js
App({
onLaunch: function() {
wx.login({
success: function(res) {
if (res.code) {
//發(fā)起網(wǎng)絡請求
wx.request({
url: 'https://test.com/onLogin',
data: {
code: res.code
}
})
} else {
console.log('獲取用戶登錄態(tài)失斔寻伞市俊!' + res.errMsg)
}
}
});
}
})
code 換取 session_key
? 這是一個 HTTPS 接口,開發(fā)者服務器使用登錄憑證 code 獲取 session_key 和 openid滤奈。其中 session_key 是對用戶數(shù)據(jù)進行加密簽名的密鑰摆昧。為了自身應用安全,session_key 不應該在網(wǎng)絡上傳輸蜒程。
接口地址:
//正常返回的JSON數(shù)據(jù)包
{
"openid": "OPENID",
"session_key": "SESSIONKEY"
}
//錯誤時返回JSON數(shù)據(jù)包(示例為Code無效)
{
"errcode": 40029,
"errmsg": "invalid code"
}
13 微信小程序支付
要先到微信公眾平臺開通微信支付绅你,綁定微信支付商戶號
步驟
A:小程序向服務端發(fā)送商品詳情、金額昭躺、openid
B:服務端向微信統(tǒng)一下單
C:服務器收到返回信息二次簽名發(fā)回給小程序
D:小程序發(fā)起支付
E:服務端收到回調(diào)
小程序向服務端發(fā)送商品詳情忌锯、金額、openid
wx.request({
url:'test.php',
data:{
openid:'', //openid
tatal_free:'', //商品金額
wx_body:'' //商品描述
}
})
然后服務端接收小程序發(fā)來的信息后 會發(fā)起統(tǒng)一下單
服務器下單完成后會返回簽名參數(shù)
{
'timeStamp': '',
'nonceStr': '',
'package': '',
'signType': 'MD5',
'paySign': ''
}
前端拿到簽名參數(shù)后發(fā)起支付
wx.requestPayment({
'timeStamp': '',
'nonceStr': '',
'package': '',
'signType': 'MD5',
'paySign': '',
'success':function(res){
wx.showToast({
title: '支付成功'
})
},
'fail':function(res){},
'complete':function(res){}
})
幾點注意
如果有需要领炫,建議只在項目目錄中放置少量icon類的小圖片偶垮,其他大圖片可以上傳到自己的服務器或者網(wǎng)盤中,然后在src中設置圖片的網(wǎng)絡資源地址。
wx.request(object)中method的請求方式默認為GET似舵。有效值: OPTIONS,GET,HEAD,POST,PUT,DELETE,TRACE,CONNECT脚猾。經(jīng)過測試,若使用小寫砚哗,在安卓中會導致無法發(fā)起請求龙助,而在開發(fā)者工具和ios中則正常。
小程序執(zhí)行wx.request(object)發(fā)送請求并收到success(成功)的消息后蛛芥,會自動收到這樣的回調(diào)參數(shù):
{
data:'服務器返回的數(shù)據(jù)',
errMsg:'錯誤信息',
statusCode:HTTP狀態(tài)碼
}
特別注意提鸟,在開發(fā)者工具和ios中,res.statusCode的數(shù)據(jù)類型是一個數(shù)值常空,而在Android中的數(shù)據(jù)類型是一個字符串沽一,所以在判斷res.statusCode時不能直接使用===操作符,而應該使用==操作符漓糙。