首先先在微信公眾平台上注冊小程序個人賬號。然后下載微信web開發者工具,新建小程序項目,如下圖所示:
下面是小程序項目公有目錄與私有目錄的工程結構了解
命名帶有app前綴的一般都是主目錄也就是公有目錄,一般包含三個文件,app.json、app.wxss、app.js(不能去修改他們的命名)
然后就是需要我們去開發的需求界面,幾乎每個界面都是一個私有目錄。一般都包含四個文件,*.js,*.wxml,*.wxss,*.json。
接下來,讓我們手寫新建一個自己的第一個小程序demo
全局配置
app.json
文件用來對微信小程序進行全局配置,決定頁面文件的路徑、窗口表現、設置網絡超時時間、設置多 tab 等。
以下是一個包含了部分常用配置選項的 app.json
:
{
"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 }
app.json 配置項列表
屬性 | 類型 | 必填 | 描述 | 支持版本 |
---|---|---|---|---|
pages | String Array | 是 | 頁面路徑列表 | |
window | Object | 否 | 全局的默認窗口表現 | |
tabBar | Object | 否 | 底部 tab 欄的表現 |
|
networkTimeout | Object | 否 | 網絡超時時間 | |
debug | Boolean | 否 | 是否開啟 debug 模式,默認關閉 | |
functionalPages | Boolean | 否 | 是否啟用插件功能頁,默認關閉 | 2.1.0 |
subPackages | Object Array | 否 | 分包結構配置 | 1.7.3 |
workers | String | 否 | Worker 代碼放置的目錄 |
1.9.90 |
requiredBackgroundModes | Array | 否 | 需要在后台使用的能力,如「音樂播放」 | |
plugins | Object | 否 | 使用到的插件 | 1.9.6 |
preloadRule | Object | 否 | 分包預下載規則 | 2.3.0 |
resizable | Boolean | 否 | iPad 小程序是否支持屏幕旋轉,默認關閉 | 2.3.0 |
pages
用於指定小程序由哪些頁面組成,每一項都對應一個頁面的 路徑+文件名 信息。文件名不需要寫文件后綴,框架會自動去尋找對於位置的 .json
, .js
, .wxml
, .wxss
四個文件進行處理。
tabBar
如果小程序是一個多 tab 應用(客戶端窗口的底部或頂部有 tab 欄可以切換頁面),可以通過 tabBar 配置項指定 tab 欄的表現,以及 tab 切換時顯示的對應頁面。如下圖所示:
其中,pages屬性中誰寫在第一行,誰就是首頁。
頁面目錄的具體配置
js文件進行數據綁定
wxss文件進行樣式配置
wxml文件具體頁面呈現
在小程序中的數據綁定形式主要是{{ }}
wxss樣式文件的使用
WXSS
WXSS(WeiXin Style Sheets)是一套樣式語言,用於描述 WXML 的組件樣式。
WXSS 用來決定 WXML 的組件應該怎么顯示。
為了適應廣大的前端開發者,WXSS 具有 CSS 大部分特性。同時為了更適合開發微信小程序,WXSS 對 CSS 進行了擴充以及修改。
與 CSS 相比,WXSS 擴展的特性有:
- 尺寸單位
- 樣式導入
尺寸單位
- rpx(responsive pixel): 可以根據屏幕寬度進行自適應。規定屏幕寬為750rpx。如在 iPhone6 上,屏幕寬度為375px,共有750個物理像素,則750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。
設備 | rpx換算px (屏幕寬度/750) | px換算rpx (750/屏幕寬度) |
---|---|---|
iPhone5 | 1rpx = 0.42px | 1px = 2.34rpx |
iPhone6 | 1rpx = 0.5px | 1px = 2rpx |
iPhone6 Plus | 1rpx = 0.552px | 1px = 1.81rpx |
建議: 開發微信小程序時設計師可以用 iPhone6 作為視覺稿的標准。
注意: 在較小的屏幕上不可避免的會有一些毛刺,請在開發時盡量避免這種情況。
樣式導入
使用@import
語句可以導入外聯樣式表,@import
后跟需要導入的外聯樣式表的相對路徑,用;
表示語句結束。
示例代碼:
/** common.wxss **/ .small-p { padding:5px; }
/** app.wxss **/ @import "common.wxss"; .middle-p { padding:15px; }
內聯樣式
框架組件上支持使用 style、class 屬性來控制組件的樣式。
- style:靜態的樣式統一寫到 class 中。style 接收動態的樣式,在運行時會進行解析,請盡量避免將靜態的樣式寫進 style 中,以免影響渲染速度。
<view style="color:{{color}};" />
- class:用於指定樣式規則,其屬性值是樣式規則中類選擇器名(樣式類名)的集合,樣式類名不需要帶上
.
,樣式類名之間用空格分隔。
<view class="normal_view" />
選擇器
目前支持的選擇器有:
選擇器 | 樣例 | 樣例描述 |
---|---|---|
.class | .intro |
選擇所有擁有 class="intro" 的組件 |
#id | #firstname |
選擇擁有 id="firstname" 的組件 |
element | view |
選擇所有 view 組件 |
element, element | view, checkbox |
選擇所有文檔的 view 組件和所有的 checkbox 組件 |
::after | view::after |
在 view 組件后邊插入內容 |
::before | view::before |
在 view 組件前邊插入內容 |
全局樣式與局部樣式
定義在 app.wxss 中的樣式為全局樣式,作用於每一個頁面。在 page 的 wxss 文件中定義的樣式為局部樣式,只作用在對應的頁面,並會覆蓋 app.wxss 中相同的選擇器。
1、小程序的wxss文件的尺度單位主要是rpx(
- rpx(responsive pixel): 可以根據屏幕寬度進行自適應。規定屏幕寬為750rpx。如在 iPhone6 上,屏幕寬度為375px,共有750個物理像素,則750rpx = 375px = 750物理像素,1rpx = 0.5px = 1物理像素。
)
2、外部樣式導入
使用@import
語句可以導入外聯樣式表,@import
后跟需要導入的外聯樣式表的相對路徑,用;
表示語句結束。
3、內聯樣式綁定
小程序默認加載的頁面
小程序app的生命周期
App()
函數用來注冊一個小程序。接受一個 Object
參數,其指定小程序的生命周期回調等。
App() 必須在 app.js
中調用,必須調用且只能調用一次。不然會出現無法預期的后果。
Object參數說明:
屬性 | 類型 | 描述 | 觸發時機 |
---|---|---|---|
onLaunch | Function | 生命周期回調—監聽小程序初始化 | 小程序初始化完成時(全局只觸發一次) |
onShow | Function | 生命周期回調—監聽小程序顯示 | 小程序啟動,或從后台進入前台顯示時 |
onHide | Function | 生命周期回調—監聽小程序隱藏 | 小程序從前台進入后台時 |
onError | Function | 錯誤監聽函數 | 小程序發生腳本錯誤,或者 api 調用失敗時觸發,會帶上錯誤信息 |
onPageNotFound | Function | 頁面不存在監聽函數 | 小程序要打開的頁面不存在時觸發,會帶上頁面信息回調該函數 |
其他 | Any | 開發者可以添加任意的函數或數據到 Object 參數中,用 this 可以訪問 |
前台、后台定義: 當用戶點擊左上角關閉,或者按了設備 Home 鍵離開微信,小程序並沒有直接銷毀,而是進入了后台;當再次進入微信或再次打開小程序,又會從后台進入前台。需要注意的是:只有當小程序進入后台一定時間,或者系統資源占用過高,才會被真正的銷毀。
關閉小程序(基礎庫版本1.1.0開始支持): 當用戶從掃一掃、轉發等入口(場景值為1007, 1008, 1011, 1025)進入小程序,且沒有置頂小程序的情況下退出,小程序會被銷毀。
小程序運行機制在基礎庫版本 1.4.0 有所改變: 上一條關閉邏輯在新版本已不適用。詳情
示例代碼:
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' })
onLaunch(Object)
小程序初始化完成時觸發,全局只觸發一次。
Object 參數說明:
字段 | 類型 | 說明 |
---|---|---|
path | String | 打開小程序的路徑 |
query | Object | 打開小程序的query |
scene | Number | 打開小程序的場景值 |
shareTicket | String | shareTicket,詳見 獲取更多轉發信息 |
referrerInfo | Object | 當場景為由從另一個小程序或公眾號或App打開時,返回此字段 |
referrerInfo.appId | String | 來源小程序或公眾號或App的 appId,詳見下方說明 |
referrerInfo.extraData | Object | 來源小程序傳過來的數據,scene=1037或1038時支持 |
以下場景支持返回 referrerInfo.appId:
場景值 | 場景 | appId 信息含義 |
---|---|---|
1020 | 公眾號 profile 頁相關小程序列表 | 來源公眾號 appId |
1035 | 公眾號自定義菜單 | 來源公眾號 appId |
1036 | App 分享消息卡片 | 來源應用 appId |
1037 | 小程序打開小程序 | 來源小程序 appId |
1038 | 從另一個小程序返回 | 來源小程序 appId |
1043 | 公眾號模板消息 | 來源公眾號 appId |
onShow(Object)
小程序啟動,或從后台進入前台顯示時觸發。
Object 參數說明:
與 onLaunch
一致
onHide()
小程序從前台進入后台時觸發。
onError(String error)
小程序發生腳本錯誤,或者 api 調用失敗時觸發。
參數說明
名稱 | 類型 | 說明 |
---|---|---|
error | String | 錯誤信息,包含堆棧 |
onPageNotFound(Object)
基礎庫 1.9.90 開始支持,低版本需做兼容處理。
小程序要打開的頁面不存在時觸發。
Object 參數說明:
字段 | 類型 | 說明 |
---|---|---|
path | String | 不存在頁面的路徑 |
query | Object | 打開不存在頁面的 query |
isEntryPage | Boolean | 是否本次啟動的首個頁面(例如從分享等入口進來,首個頁面是開發者配置的分享頁面) |
開發者可以在 onPageNotFound
回調中進行重定向處理,但必須在回調中同步處理,異步處理(例如 setTimeout 異步執行)無效。
示例代碼:
App({
onPageNotFound(res) {
wx.redirectTo({
url: 'pages/...' }) // 如果是 tabbar 頁面,請使用 wx.switchTab } })
注意:
- 如果開發者沒有添加
onPageNotFound
監聽,當跳轉頁面不存在時,將推入微信客戶端原生的頁面不存在提示頁面。 - 如果
onPageNotFound
回調中又重定向到另一個不存在的頁面,將推入微信客戶端原生的頁面不存在提示頁面,並且不再回調onPageNotFound
。
getApp(Object)
全局的 getApp()
函數可以用來獲取到小程序 App
實例。
Object 參數說明:
字段 | 類型 | 說明 | 最低版本 |
---|---|---|---|
allowDefault | Boolean | 在 App 未定義時返回默認實現。當App被調用時,默認實現中定義的屬性會被覆蓋合並到App中。一般用於獨立分包。 |
2.2.4 |
示例代碼:
// other.js var appInstance = getApp() console.log(appInstance.globalData) // I am global data
注意:
- 不要在定義於
App()
內的函數中調用getApp()
,使用this
就可以拿到 app 實例。 - 通過
getApp()
獲取實例之后,不要私自調用生命周期函數。
小程序調試js文件
1、新建小程序項目my-debug-demo
2、因為要在手機端遠程調試,所以還需要appid。在小程序微信官方后台找到appid
3、在app.js上分別打上斷點。打開調試器。在手機上調試的時候,重開小程序,點擊vConsole進入調試模式。
私有頁面的生命周期以及導航
Page(Object)
Page(Object)
函數用來注冊一個頁面。接受一個 Object
類型參數,其指定頁面的初始數據、生命周期回調、事件處理函數等。
Object 參數說明:
屬性 | 類型 | 描述 |
---|---|---|
data | Object | 頁面的初始數據 |
onLoad | Function | 生命周期回調—監聽頁面加載 |
onShow | Function | 生命周期回調—監聽頁面顯示 |
onReady | Function | 生命周期回調—監聽頁面初次渲染完成 |
onHide | Function | 生命周期回調—監聽頁面隱藏 |
onUnload | Function | 生命周期回調—監聽頁面卸載 |
onPullDownRefresh | Function | 監聽用戶下拉動作 |
onReachBottom | Function | 頁面上拉觸底事件的處理函數 |
onShareAppMessage | Function | 用戶點擊右上角轉發 |
onPageScroll | Function | 頁面滾動觸發事件的處理函數 |
onTabItemTap | Function | 當前是 tab 頁時,點擊 tab 時觸發 |
其他 | Any | 開發者可以添加任意的函數或數據到 Object 參數中,在頁面的函數中用 this 可以訪問 |
Object 內容在頁面加載時會進行一次深拷貝,需考慮數據大小對頁面加載的開銷
示例代碼:
//index.js 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. }, onPageScroll: function() { // Do something when page scroll }, onTabItemTap(item) { console.log(item.index) console.log(item.pagePath) console.log(item.text) }, // Event handler. viewTap: function() { this.setData({ text: 'Set some data for updating view.' }, function() { // this is setData callback }) }, customData: { hi: 'MINA' } })
data
data
是頁面第一次渲染使用的初始數據。
頁面加載時,data
將會以JSON
字符串的形式由邏輯層傳至渲染層,因此data
中的數據必須是可以轉成JSON
的類型:字符串,數字,布爾值,對象,數組。
渲染層可以通過 WXML 對數據進行綁定。
示例代碼:
<view>{{text}}</view> <view>{{array[0].msg}}</view>
Page({
data: { text: 'init data', array: [{msg: '1'}, {msg: '2'}] } })
生命周期回調函數
生命周期的觸發以及頁面的路由方式詳見
onLoad(Object query)
頁面加載時觸發。一個頁面只會調用一次,可以在 onLoad 的參數中獲取打開當前頁面路徑中的參數。
參數說明
名稱 | 類型 | 說明 |
---|---|---|
query | Object | 打開當前頁面路徑中的參數 |
onShow()
頁面顯示/切入前台時觸發。
onReady()
頁面初次渲染完成時觸發。一個頁面只會調用一次,代表頁面已經准備妥當,可以和視圖層進行交互。
注意:對界面內容進行設置的 API 如wx.setNavigationBarTitle
,請在onReady
之后進行。詳見生命周期
onHide()
頁面隱藏/切入后台時觸發。 如 navigateTo
或底部 tab
切換到其他頁面,小程序切入后台等。
onUnload()
頁面卸載時觸發。如redirectTo
或navigateBack
到其他頁面時。
頁面事件處理函數
onPullDownRefresh()
監聽用戶下拉刷新事件。
- 需要在
app.json
的window
選項中或頁面配置中開啟enablePullDownRefresh
。 - 可以通過
wx.startPullDownRefresh
觸發下拉刷新,調用后觸發下拉刷新動畫,效果與用戶手動下拉刷新一致。 - 當處理完數據刷新后,
wx.stopPullDownRefresh
可以停止當前頁面的下拉刷新。
onReachBottom()
監聽用戶上拉觸底事件。
onPageScroll(Object)
監聽用戶滑動頁面事件。
Object 參數說明:
屬性 | 類型 | 說明 |
---|---|---|
scrollTop | Number | 頁面在垂直方向已滾動的距離(單位px) |
onShareAppMessage(Object)
監聽用戶點擊頁面內轉發按鈕(<button>
組件 open-type="share"
)或右上角菜單“轉發”按鈕的行為,並自定義轉發內容。
注意:只有定義了此事件處理函數,右上角菜單才會顯示“轉發”按鈕
Object 參數說明:
參數 | 類型 | 說明 | 最低版本 |
---|---|---|---|
from | String | 轉發事件來源。button :頁面內轉發按鈕;menu :右上角轉發菜單 |
1.2.4 |
target | Object | 如果 from 值是 button ,則 target 是觸發這次轉發事件的 button ,否則為 undefined |
1.2.4 |
webViewUrl | String | 頁面中包含<web-view> 組件時,返回當前<web-view> 的url |
1.6.4 |
此事件需要 return 一個 Object,用於自定義轉發內容,返回內容如下:
自定義轉發內容
字段 | 說明 | 默認值 | 最低版本 |
---|---|---|---|
title | 轉發標題 | 當前小程序名稱 | |
path | 轉發路徑 | 當前頁面 path ,必須是以 / 開頭的完整路徑 | |
imageUrl | 自定義圖片路徑,可以是本地文件路徑、代碼包文件路徑或者網絡圖片路徑。支持PNG及JPG。顯示圖片長寬比是 5:4。 | 使用默認截圖 | 1.5.0 |
示例代碼
Page({
onShareAppMessage: function (res) { if (res.from === 'button') { // 來自頁面內轉發按鈕 console.log(res.target) } return { title: '自定義轉發標題', path: '/page/user?id=123' } } })
onTabItemTap(Object)
基礎庫 1.9.0 開始支持,低版本需做兼容處理。
點擊 tab 時觸發
Object 參數說明:
參數 | 類型 | 說明 | 最低版本 |
---|---|---|---|
index | String | 被點擊tabItem的序號,從0開始 | 1.9.0 |
pagePath | String | 被點擊tabItem的頁面路徑 | 1.9.0 |
text | String | 被點擊tabItem的按鈕文字 | 1.9.0 |
示例代碼:
Page({
onTabItemTap(item) {
console.log(item.index) console.log(item.pagePath) console.log(item.text) } })
組件事件處理函數
Page
中還可以定義組件事件處理函數。在渲染層的組件中加入事件綁定,當事件被觸發時,就會執行 Page 中定義的事件處理函數。
示例代碼:
<view bindtap="viewTap"> click me </view>
Page({
viewTap: function() { console.log('view tap') } })
Page.route
基礎庫 1.2.0 開始支持,低版本需做兼容處理。
到當前頁面的路徑,類型為String
。
Page({
onShow: function() { console.log(this.route) } })
Page.prototype.setData(Object data, Function callback)
setData
函數用於將數據從邏輯層發送到視圖層(異步),同時改變對應的 this.data
的值(同步)。
參數說明
字段 | 類型 | 必填 | 描述 | 最低版本 |
---|---|---|---|---|
data | Object | 是 | 這次要改變的數據 | |
callback | Function | 否 | setData引起的界面更新渲染完畢后的回調函數 | 1.5.0 |
Object
以 key: value
的形式表示,將 this.data
中的 key
對應的值改變成 value
。
其中 key
可以以數據路徑的形式給出,支持改變數組中的某一項或對象的某個屬性,如 array[2].message
,a.b.c.d
,並且不需要在 this.data 中預先定義。
注意:
- 直接修改 this.data 而不調用 this.setData 是無法改變頁面的狀態的,還會造成數據不一致。
- 僅支持設置可 JSON 化的數據。
- 單次設置的數據不能超過1024kB,請盡量避免一次設置過多的數據。
- 請不要把 data 中任何一項的 value 設為
undefined
,否則這一項將不被設置並可能遺留一些潛在問題。
示例代碼:
<!--index.wxml--> <view>{{text}}</view> <button bindtap="changeText"> Change normal data </button> <view>{{num}}</view> <button bindtap="changeNum"> Change normal num </button> <view>{{array[0].text}}</view> <button bindtap="changeItemInArray"> Change Array data </button> <view>{{object.text}}</view> <button bindtap="changeItemInObject"> Change Object data </button> <view>{{newField.text}}</view> <button bindtap="addNewField"> Add new data </button>
// index.js Page({ data: { text: 'init data', num: 0, array: [{text: 'init data'}], object: { text: 'init data' } }, changeText: function() { // this.data.text = 'changed data' // 不要直接修改 this.data // 應該使用 setData this.setData({ text: 'changed data' }) }, changeNum: function() { // 或者,可以修改 this.data 之后馬上用 setData 設置一下修改了的字段 this.data.num = 1 this.setData({ num: this.data.num }) }, changeItemInArray: function() { // 對於對象或數組字段,可以直接修改一個其下的子字段,這樣做通常比修改整個對象或數組更好 this.setData({ 'array[0].text':'changed data' }) }, changeItemInObject: function(){ this.setData({ 'object.text': 'changed data' }); }, addNewField: function() { this.setData({ 'newField.text': 'new data' }) } })
生命周期
以下內容你不需要立馬完全弄明白,不過以后它會有幫助。
下圖說明了 Page 實例的生命周期。
wxs模塊講解--頁面引用
新建wxs模板文件:
在wxs.wxml文件上創建相應內容
在內部去引用另一個wxs
小程序模板在外部頁面的引用
頁面引用外部wxml通用頁面