一、基礎(chǔ)介紹
小程序是什么
小程序可以視為只能用微信打開和瀏覽的網(wǎng)站。小程序和網(wǎng)頁的技術(shù)模型是一樣的,用到的 JavaScript 語言和 CSS 樣式也是一樣的,只是網(wǎng)頁的 HTML 標(biāo)簽被修改成了 WXML 標(biāo)簽,CSS標(biāo)簽被修改成了WXSS標(biāo)簽。
小程序最大的優(yōu)勢(shì)就是基于微信,也不需要考慮iOS和Android不同平臺(tái)間的差異,同時(shí)微信也提供了豐富的API接口,例如拍攝、錄音、語音識(shí)別、二維碼等,小程序可以利用原生能力,快速進(jìn)行開發(fā)。
開發(fā)準(zhǔn)備
去微信公眾平臺(tái)注冊(cè),申請(qǐng)一個(gè)AppId。
下載小程序開發(fā)工具,微信開發(fā)者工具。
創(chuàng)建一個(gè)項(xiàng)目


調(diào)試運(yùn)行項(xiàng)目
小程序支持實(shí)時(shí)預(yù)覽,代碼修改后,左邊預(yù)覽窗口就可以直接看到修改后的效果。
也可以點(diǎn)擊預(yù)覽按鈕,通過微信的掃一掃在手機(jī)上體驗(yàn)。

二、小程序項(xiàng)目結(jié)構(gòu)
小程序包含一個(gè)描述整體程序的 app 和若干個(gè)描述頁面的 page 組成。

一個(gè)小程序主體部分由三個(gè)文件組成,必須放在項(xiàng)目的根目錄,如下:
| 文件 | 必需 | 作用 |
|---|---|---|
| app.js | 是 | 小程序邏輯 |
| app.json | 是 | 小程序公共配置 |
| app.wxss | 否 | 小程序公共樣式表 |
一個(gè)小程序頁面由四個(gè)文件組成,分別是:
| 文件類型 | 必需 | 作用 |
|---|---|---|
| js | 是 | 頁面邏輯 |
| wxml | 是 | 頁面結(jié)構(gòu) |
| json | 否 | 頁面配置 |
| wxss | 否 | 頁面樣式表 |
注冊(cè)小程序
每個(gè)小程序都需要在 app.js 中調(diào)用 App 方法注冊(cè)小程序?qū)嵗?,綁定生命周期回調(diào)函數(shù)、錯(cuò)誤監(jiān)聽和頁面不存在監(jiān)聽函數(shù)等。詳細(xì)的參數(shù)含義和使用請(qǐng)參考 App 參考文檔 。
// app.js
App({
onLaunch (options) {
// Do something initial when launch.
},
onShow (options) {
// Do something when show.
},
onHide () {
// Do something when hide.
},
onError (msg) {
console.log(msg)
},
globalData: 'I am global data'
})
整個(gè)小程序只有一個(gè) App 實(shí)例,是全部頁面共享的。開發(fā)者可以通過 getApp 方法獲取到全局唯一的 App 實(shí)例,獲取App上的數(shù)據(jù)或調(diào)用開發(fā)者注冊(cè)在 App 上的函數(shù)。它的作用有些類似Android 中的 Application。
// xxx.js
const appInstance = getApp()
console.log(appInstance.globalData) // I am global data
全局配置
app.json 小程序的全局配置,用于聲明頁面文件的路徑、窗口顯示、設(shè)置多tab等。完整配置項(xiàng)說明請(qǐng)參考小程序全局配置
{
"pages": [
"pages/index/index",
"pages/logs/index"
],
"window": {
"navigationBarTitleText": "Demo"
},
"tabBar": {
"list": [{
"pagePath": "pages/index/index",
"text": "首頁"
}, {
"pagePath": "pages/logs/index",
"text": "日志"
}]
},
"networkTimeout": {
"request": 10000,
"downloadFile": 10000
},
"debug": true
}
注冊(cè)頁面
小程序的每個(gè)頁面,都需要在頁面對(duì)應(yīng)的js文件中進(jìn)行注冊(cè),同時(shí)可以指定頁面的初始數(shù)據(jù)、生命周期回調(diào)、事件處理函數(shù)等。
//index.js
Page({
data: {
text: "This is page data."
},
onLoad: function(options) {
// 頁面創(chuàng)建時(shí)執(zhí)行
},
onShow: function() {
// 頁面出現(xiàn)在前臺(tái)時(shí)執(zhí)行
},
onReady: function() {
// 頁面首次渲染完畢時(shí)執(zhí)行
},
onHide: function() {
// 頁面從前臺(tái)變?yōu)楹笈_(tái)時(shí)執(zhí)行
},
onUnload: function() {
// 頁面銷毀時(shí)執(zhí)行
},
onPullDownRefresh: function() {
// 觸發(fā)下拉刷新時(shí)執(zhí)行
},
onReachBottom: function() {
// 頁面觸底時(shí)執(zhí)行
},
onShareAppMessage: function () {
// 頁面被用戶分享時(shí)執(zhí)行
},
onPageScroll: function() {
// 頁面滾動(dòng)時(shí)執(zhí)行
},
onResize: function() {
// 頁面尺寸變化時(shí)執(zhí)行
},
onTabItemTap(item) {
// tab 點(diǎn)擊時(shí)執(zhí)行
console.log(item.index)
console.log(item.pagePath)
console.log(item.text)
}
})
詳細(xì)的參數(shù)含義和使用請(qǐng)參考 Page 參考文檔 。
頁面配置
每一個(gè)小程序頁面也可以使用同名 .json 文件來對(duì)本頁面的窗口表現(xiàn)進(jìn)行配置,頁面中配置項(xiàng)會(huì)覆蓋 app.json 的 window 中相同的配置項(xiàng)。
完整配置項(xiàng)說明請(qǐng)參考小程序頁面配置
{
"navigationBarBackgroundColor": "#ffffff",
"navigationBarTextStyle": "black",
"navigationBarTitleText": "微信接口功能演示",
"backgroundColor": "#eeeeee",
"backgroundTextStyle": "light"
}
三、頁面
WXML 模板
wxml文件用來描述頁面展示的代碼:
<view class="container">
<view class="userinfo">
<button wx:if="{{!hasUserInfo && canIUse}}"> 獲取頭像昵稱 </button>
<block wx:else>
<image src="{{userInfo.avatarUrl}}" background-size="cover"></image>
<text class="userinfo-nickname">{{userInfo.nickName}}</text>
</block>
</view>
<view class="usermotto">
<text class="user-motto">{{motto}}</text>
</view>
</view>
它和html頁面主要有以下兩個(gè)區(qū)別:
- 標(biāo)簽名字不太一樣,微信小程序提供了豐富的組件供開發(fā)者使用,所以不需要使用類似 div、p、span的基礎(chǔ)標(biāo)簽。
- 多了一些
wx:if="{{!hasUserInfo && canIUse}}"這種{{}}的表達(dá)式,用的是 MVVM 的開發(fā)模式,將頁面渲染和邏輯進(jìn)行分離。通過 {{ }} 的語法把一個(gè)變量綁定到界面上,稱為數(shù)據(jù)綁定。僅僅通過數(shù)據(jù)綁定還不夠完整的描述狀態(tài)和界面的關(guān)系,還需要if/else,for等控制能力,在小程序里邊,這些控制能力都用wx:開頭的屬性來表達(dá)。
JS交互邏輯
小程序?yàn)榻M件提供了很多交互屬性,且使用非常簡單:
//xxx.wxml
<view>{{ msg }}</view>
<button bindtap="clickMe">點(diǎn)擊我</button>
//xxx.js
Page({
clickMe: function() {
this.setData({ msg: "Hello World" })
}
})
更詳細(xì)的事件可以參考文檔 WXML - 事件 。
這里需要注意的是,直接修改 this.data 而不調(diào)用 this.setData 是無法改變頁面的狀態(tài)的。
頁面跳轉(zhuǎn)
框架以棧的形式維護(hù)了當(dāng)前的所有頁面。 當(dāng)發(fā)生頁面切換的時(shí)候,頁面棧的表現(xiàn)如下:
| 路由方式 | 頁面棧表現(xiàn) | API |
|---|---|---|
| 打開新頁面 | 新頁面入棧 | wx.navigateTo |
| 頁面重定向 | 當(dāng)前頁面出棧,新頁面入棧 | wx.redirectTo |
| 頁面返回 | 頁面不斷出棧,直到目標(biāo)返回頁 | wx.navigateBack |
| Tab 切換 | 頁面全部出棧,只留下新的 Tab 頁面 | wx.switchTab |
| 重加載 | 頁面全部出棧,只留下新的頁面 | wx.reLaunch |
開發(fā)者可以使用 getCurrentPages() 函數(shù)獲取當(dāng)前頁面棧。
具體使用:
//跳轉(zhuǎn)到test界面
skipTest(event) {
wx.navigateTo({
url: '../test/test',
})
}
四、API 使用
存儲(chǔ)
每個(gè)微信小程序都有自己的本地緩存,可以通過 wx.setStorage/wx.setStorageSync、wx.getStorage/wx.getStorageSync、wx.clearStorage/wx.clearStorageSync,wx.removeStorage/wx.removeStorageSync 對(duì)本地緩存進(jìn)行讀寫和清理。
其中以 Sync 結(jié)尾的代表同步操作,二者的區(qū)別在于,異步不會(huì)阻塞當(dāng)前任務(wù)。
具體使用:
setStorageTest(event) {
wx.setStorage({
key: 'name',
data: 'huangm',
success(res) {
console.log("storage success")
}
})
console.log("storage end")
},
getStorageTest(event) {
const that = this
wx.getStorage({
key: 'name',
success (res) {
that.setData({
name: res.data
})
console.log(res.data)
}
})
console.log('get Storage end')
},
deleteStorageTest(event) {
const that = this
wx.removeStorage({
key: 'name',
success(res) {
that.getStorageTest()
}
})
}
隔離策略
同一個(gè)微信用戶,同一個(gè)小程序 storage 上限為 10MB。storage 以用戶維度隔離,同一臺(tái)設(shè)備上,A 用戶無法讀取到 B 用戶的數(shù)據(jù);不同小程序之間也無法互相讀寫數(shù)據(jù)。
網(wǎng)絡(luò)請(qǐng)求
小程序支持普通 HTTPS 請(qǐng)求(wx.request)、上傳文件(wx.uploadFile)、下載文件(wx.downloadFile) 和 WebSocket 通信(wx.connectSocket)。
具體使用:
wx.request({
url: 'https://www.wanandroid.com/banner/json',
success (res) {
console.log(res.data.data)
that.setData({
bannerList: res.data.data
})
}
})
調(diào)用Native方法
小程序提供很多設(shè)備相關(guān)API,如日歷、聯(lián)系人、藍(lán)牙、電量、掃碼等。
使用如下:
wx.scanCode({
onlyFromCamera: true,
success(res) {
console.log(res)
},
fail(res) {
console.log(res)
}
})
五、自定義組件
在現(xiàn)有官方組件無法滿足我們開發(fā)需求的時(shí)候,小程序也支持 自定義組件。
組件模板
組件模板和頁面類似,也是包含 xxx.js、xxx.wxml、xxx.wxss、xxx.json

創(chuàng)建一個(gè)button組件
- 配置組件,testbutton.json
{
"component" : true
}
- 繪制界面和樣式
testbutton.wxml
<view class="test-button" bindtap="onClick">
{{content}}
</view>
testbutton.wxss
.test-button {
width: 100%;
height: 100rpx;
background-color: burlywood;
display: flex;
align-items: center;
text-align: center;
justify-content: center;
color: cornflowerblue;
}
- 構(gòu)造組件
Component 構(gòu)造器可以指定組件的屬性、數(shù)據(jù)、方法等,具體使用可以參考 Component 構(gòu)造器。
testbutton.js
Component({
//聲明屬性
properties:{
content:{
type: String,
value: 'test'
}
},
methods: {
onClick: function() {
console.log('test button onclick')
var myEventDetail = {
toastContent: 'This is a test-button'
}
var myEventOption = {}
//聲明事件,組件間傳遞數(shù)據(jù)
this.triggerEvent('onClick', myEventDetail, myEventOption)
}
}
})
- 使用自定義組件
使用的界面需要通過 usingComponents 引用該組件
{
"usingComponents": {
"Test-Button": "/component/testbutton/testbutton"
},
"navigationBarTitleText": "項(xiàng)目"
}
界面中直接使用該標(biāo)簽
<Test-Button content="This is a test-button" bindonClick="onClick"></Test-Button>
點(diǎn)擊后彈出一個(gè)toast
onClick(event) {
console.log(event)
wx.showToast({
title: event.detail.toastContent,
duration: 2000
})
}

六、博客閱讀demo開發(fā)
通過開發(fā)一個(gè)簡單的demo,可以對(duì)以上的內(nèi)容有更直觀的了解。
玩Android API:https://www.wanandroid.com/blog/show/2
-
tab主界面,展示最近博客列表
首頁.png -
點(diǎn)擊瀏覽具體文章
瀏覽文章.png
-
根據(jù)作者,展示文章列表
文章.png
參考:


