一、小程式代碼構成

?在上一篇文章中,我們通過開發者工具載入模板快速創建了一個QuickStart專案,這個專案里邊生成了不同型別的檔案:
- .json 后綴的 JSON 組態檔
- .wxml 后綴的 WXML 模板檔案
- .wxss 后綴的 WXSS 樣式檔案
- .js 后綴的 JS 腳本邏輯檔案
1.JSON 配置
JSON 是一種資料格式,并不是編程語言,在小程式中,JSON扮演的靜態配置的角色,
可以看到在專案的根目錄有一個 app.json 和 project.config.json,此外在 pages/index 目錄下還有一個 index.json,依次來說明一下它們的用途,

1.1 小程式配置 app.json
app.json 是當前小程式的全域配置,包括了小程式的所有頁面路徑、界面表現、網路超時時間、底部 tab 等,QuickStart 專案里邊的 app.json 配置內容如下:
{
"pages":[
"pages/index/index",
"pages/logs/logs"
],
"window":{
"backgroundTextStyle":"light",
"navigationBarBackgroundColor": "#fff",
"navigationBarTitleText": "Weixin",
"navigationBarTextStyle":"black"
},
"style": "v2",
"sitemapLocation": "sitemap.json"
}
簡單說一下這個配置各個項的含義:
pages欄位——用于描述當前小程式所有頁面路徑,這是為了讓微信客戶端知道當前你的小程式頁面定義在哪個目錄,window欄位 —— 定義小程式所有頁面的頂部背景顏色,文字顏色定義等,
其他配置項細節可以參考檔案 小程式的配置 app.json ,
1.2 工具配置 project.config.json
通常大家在使用一個工具的時候,都會針對各自喜好做一些個性化配置,例如界面顏色、編譯配置等等,當你換了另外一臺電腦重新安裝工具的時候,你還要重新配置,
考慮到這點,小程式開發者工具在每個專案的根目錄都會生成一個 project.config.json,你在工具上做的任何配置都會寫入到這個檔案,當你重新安裝工具或者換電腦作業時,你只要載入同一個專案的代碼包,開發者工具就自動會幫你恢復到當時你開發專案時的個性化配置,其中會包括編輯器的顏色、代碼上傳時自動壓縮等等一系列選項,
其他配置項細節可以參考檔案 開發者工具的配置 ,
1.3 頁面配置 page.json
這里的 page.json 其實用來表示 pages/index目錄下的 index.json 這類和小程式頁面相關的配置,
如果你整個小程式的風格是藍色調,那么你可以在 app.json 里邊宣告頂部顏色是藍色即可,實際情況可能不是這樣,可能你小程式里邊的每個頁面都有不一樣的色調來區分不同功能模塊,因此通過 page.json,讓開發者可以獨立定義每個頁面的一些屬性,例如剛剛說的頂部顏色、是否允許下拉重繪等等,
其他配置項細節可以參考檔案 頁面配置 ,
1.4 JSON 語法
這里說一下小程式里JSON配置的一些注意事項,
JSON檔案都是被包裹在一個大括號中 {},通過key-value的方式來表達資料,JSON的Key必須包裹在一個雙引號中,在實踐中,撰寫 JSON 的時候,忘了給 Key 值加雙引號或者是把雙引號寫成單引號是常見錯誤,
JSON的值只能是以下幾種資料格式,其他任何格式都會觸發報錯,例如 JavaScript 中的 undefined,
- 數字,包含浮點數和整數
- 字串,需要包裹在雙引號中
- Bool值,true 或者 false
- 陣列,需要包裹在方括號中 []
- 物件,需要包裹在大括號中 {}
- Null
還需要注意的是 JSON 檔案中無法使用注釋,試圖添加注釋將會引發報錯,
2.WXML 模板
小程式也是學習網頁編程的思想,網頁編程采用的是 HTML + CSS + JS 這樣的組合,其中 HTML 是用來描述當前這個頁面的結構,CSS 用來描述頁面的樣子,JS 通常是用來處理這個頁面和用戶的互動,

同樣道理,在小程式中也有同樣的角色,其中 WXML 充當的就是類似 HTML 的角色,打開 pages/index/index.wxml,會看到以下的內容:
<!--index.wxml-->
<view class="container">
<view class="userinfo">
<block wx:if="{{canIUseOpenData}}">
<view class="userinfo-avatar" bindtap="bindViewTap">
<open-data type="userAvatarUrl"></open-data>
</view>
<open-data type="userNickName"></open-data>
</block>
<block wx:elif="{{!hasUserInfo}}">
<button wx:if="{{canIUseGetUserProfile}}" bindtap="getUserProfile"> 獲取頭像昵稱 </button>
<button wx:elif="{{canIUse}}" open-type="getUserInfo" bindgetuserinfo="getUserInfo"> 獲取頭像昵稱 </button>
<view wx:else> 請使用1.4.4及以上版本基礎庫 </view>
</block>
<block wx:else>
<image bindtap="bindViewTap" class="userinfo-avatar" src="{{userInfo.avatarUrl}}" mode="cover"></image>
<text class="userinfo-nickname">{{userInfo.nickName}}</text>
</block>
</view>
<view class="usermotto">
<text class="user-motto">{{motto}}</text>
</view>
</view>
和 HTML 非常相似,WXML 由標簽、屬性等等構成,但是也有很多不一樣的地方,接下來一一闡述一下:
2.1 標簽名字
之前寫 HTML 的時候,經常會用到的標簽是 div, p, span,開發者在寫一個頁面的時候可以根據這些基礎的標簽組合出不一樣的組件,例如日歷、彈窗等等,而在小程式中,既然大家都需要這些組件,所以把這些常用的組件包裝起來,大大提高我們的開發效率,
從上邊的例子可以看到,小程式的 WXML 用的標簽是 view, button, text 等等,這些標簽就是小程式給開發者包裝好的基本能力,除此之外還提供了地圖、視頻、音頻等等組件能力,
更多詳細的組件講述參考下個章節 小程式的能力,
2.2 多了一些 wx:if 這樣的屬性以及 {{ }} 這樣的運算式
在網頁的一般開發流程中,我們通常會通過 JS 操作 DOM (對應 HTML 的描述產生的樹),以引起界面的一些變化回應用戶的行為,例如,用戶點擊某個按鈕的時候,JS 會記錄一些狀態到 JS 變數里邊,同時通過 DOM API 操控 DOM 的屬性或者行為,進而引起界面一些變化,當專案越來越大的時候,你的代碼會充斥著非常多的界面互動邏輯和程式的各種狀態變數,顯然這不是一個很好的開發模式,因此就有了 MVVM 的開發模式(例如 React, Vue),提倡把渲染和邏輯分離,簡單來說就是不要再讓 JS 直接操控 DOM,JS 只需要管理狀態即可,然后再通過一種模板語法來描述狀態和界面結構的關系即可,
小程式的框架也是用到了這個思路,如果你需要把一個 Hello World 的字串顯示在界面上,
WXML 是這么寫 :
<text>{{msg}}</text>
JS 只需要管理狀態即可:
this.setData({ msg: "Hello World" })
通過 {{ }} 的語法把一個變數系結到界面上,被稱為資料系結,僅僅通過資料系結還不夠完整的描述狀態和界面的關系,還需要 if/else, for等控制能力,在小程式里邊,這些控制能力都用 wx: 開頭的屬性來表達,
更詳細的檔案可以參考 WXML
3.WXSS 樣式
WXSS 具有 CSS 大部分的特性,小程式在 WXSS 也做了一些擴充和修改,
-
新增了尺寸單位,在寫
CSS樣式時,開發者需要考慮到手機設備的螢屏會有不同的寬度和設備像素比,采用一些技巧來換算一些像素單位,WXSS在底層支持新的尺寸單位rpx,開發者可以免去換算的煩惱,只要交給小程式底層來換算即可, - 提供了全域的樣式和區域樣式,和前邊
app.json,page.json的概念相同,可以寫一個app.wxss作為全域樣式,會作用于當前小程式的所有頁面,區域頁面樣式page.wxss僅對當前頁面生效, - 此外
WXSS僅支持部分CSS選擇器,
更詳細的檔案可以參考 WXSS ,
4.JS邏輯互動
一個服務僅僅只有界面展示是不夠的,還需要和用戶做互動:回應用戶的點擊、獲取用戶的位置等等,在小程式里邊,可以通過撰寫 JS 腳本檔案來處理用戶的操作,
<view>{{ msg }}</view>
<button bindtap="clickMe">點擊我</button>
點擊 button 按鈕的時候,我們希望把界面上 msg 顯示成 "Hello World",于是我們在 button 上宣告一個屬性: bindtap ,在 JS 檔案里邊宣告了 clickMe 方法來回應這次點擊操作:
Page({
clickMe: function() {
this.setData({ msg: "Hello World" })
}
})
回應用戶的操作就是這么簡單,更詳細的事件可以參考檔案 WXML - 事件 ,
此外你還可以在 JS 中呼叫小程式提供的豐富的 API,利用這些 API 可以很方便的調起微信提供的能力,例如獲取用戶資訊、本地存盤、微信支付等,在前邊的 QuickStart 例子中,在 pages/index/index.js 就呼叫了 wx.getUserInfo 獲取微信用戶的頭像和昵稱,最后通過 setData 把獲取到的資訊顯示到界面上,更多 API 可以參考檔案 小程式的API ,
二、小程式宿主環境
我們稱微信客戶端給小程式所提供的環境為宿主環境,小程式借助宿主環境提供的能力,可以完成許多普通網頁無法完成的功能,
1.渲染層和邏輯層
首先,簡單地了解下小程式的運行環境,小程式的運行環境分成渲染層和邏輯層,其中WXML 模板和 WXSS 樣式作業在渲染層,JS 腳本作業在邏輯層,
小程式的渲染層和邏輯層分別由2個執行緒管理:渲染層的界面使用了網頁視圖進行渲染;邏輯層采用Js核執行緒運行JS腳本,一個小程式存在多個界面,所以渲染層存在多個網頁視圖執行緒,這兩個執行緒的通信會經由微信客戶端(下文中也會采用本地來代指微信客戶端)做中轉,邏輯層發送網路請求也經由本地轉發,小程式的通信模型下圖所示,

有關渲染層和邏輯層的詳細檔案參考 小程式框架 ,
2.程式與頁面
微信客戶端在打開小程式之前,會把整個小程式的代碼包下載到本地,
緊接著通過 app.json 的 pages 欄位就可以知道當前小程式的所有頁面路徑:
{
"pages":[
"pages/index/index",
"pages/logs/logs"
]
}
這個配置說明在 QuickStart 專案定義了兩個頁面,分別位于 pages/index/index 和 pages/logs/logs,而寫在 pages 欄位的第一個頁面就是這個小程式的首頁(打開小程式看到的第一個頁面),
于是微信客戶端就把首頁的代碼裝載進來,通過小程式底層的一些機制,渲染出這個首頁,
小程式啟動之后,在 app.js 定義的 App 實體的 onLaunch 回呼會被執行:
App({
onLaunch() {
// 展示本地存盤能力
const logs = wx.getStorageSync('logs') || []
logs.unshift(Date.now())
wx.setStorageSync('logs', logs)
// 登錄
wx.login({
success: res => {
// 發送 res.code 到后臺換取 openId, sessionKey, unionId
}
})
},
globalData: {
userInfo: null
}
})
整個小程式只有一個 App 實體,是全部頁面共享的,更多的事件回呼參考檔案 注冊程式 App ,
接下來我們簡單看看小程式的一個頁面是怎么寫的,
可以觀察到 pages/logs/logs 下其實是包括了4種檔案的,微信客戶端會先根據 logs.json 配置生成一個界面,頂部的顏色和文字你都可以在這個 json 檔案里邊定義好,緊接著客戶端就會裝載這個頁面的 WXML 結構和 WXSS 樣式,最后客戶端會裝載 logs.js,你可以看到 logs.js 的大體內容就是:
// logs.js
const util = require('../../utils/util.js')
Page({
data: {
logs: []
},
onl oad() {
this.setData({
logs: (wx.getStorageSync('logs') || []).map(log => {
return {
date: util.formatTime(new Date(log)),
timeStamp: log
}
})
})
}
})
Page 是一個頁面構造器,這個構造器就生成了一個頁面,在生成頁面的時候,小程式框架會把 data 資料和 index.wxml 一起渲染出最終的結構,于是就得到了你看到的小程式的樣子,
在渲染完界面之后,頁面實體就會收到一個 onLoad 的回呼,你可以在這個回呼處理你的邏輯,
有關于 Page 構造器更多詳細的檔案參考 注冊頁面 Page ,
3.組件
小程式提供了豐富的基礎組件給開發者,開發者可以像搭積木一樣,組合各種組件搭建成自己的小程式,
就像 HTML 的 div, p 等標簽一樣,在小程式里邊,你只需要在 WXML 寫上對應的組件標簽名字就可以把該組件顯示在界面上,例如,你需要在界面上顯示地圖,你只需要這樣寫即可:
<map></map>
使用組件的時候,還可以通過屬性傳遞值給組件,讓組件可以以不同的狀態去展現,例如,我們希望地圖一開始的中心的經緯度是上海東方明珠,那么你需要宣告地圖的 longitude(中心經度) 和 latitude(中心緯度)兩個屬性:
<map longitude="121.506377" latitude="31.245105"></map>
組件的內部行為也會通過事件的形式讓開發者可以感知,例如用戶點擊了地圖上的某個標記,你可以在 js 撰寫 markertap 函式來處理:
<map bindmarkertap="markertap" longitude="121.506377" latitude="31.245105"></map>
當然你也可以通過 style 或者 class 來控制組件的外層樣式,以便適應你的界面寬度高度等等,
更多的組件可以參考 小程式的組件,
4.API
為了讓開發者可以很方便的調起微信提供的能力,例如獲取用戶資訊、微信支付等等,小程式提供了很多 API 給開發者去使用,
要獲取用戶的地理位置時,只需要:
wx.getLocation({
type: 'wgs84',
success: (res) => {
var latitude = res.latitude // 緯度
var longitude = res.longitude // 經度
}
})
呼叫微信掃一掃能力,只需要:
wx.scanCode({
success: (res) => {
console.log(res)
}
})
需要注意的是:多數 API 的回呼都是異步,你需要處理好代碼邏輯的異步問題,
更多的 API 能力見 小程式的API,
通過本文已經大概了解了小程式運行的一些基本概念!!!
歡迎關注『從零開始Python+微信小程式開發』系列,持續更新中,
參考:
微信小程式官方檔案
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/332100.html
標籤:python
