小李移動開發成長記 —— 大話小程式

彭加李發表於2024-09-14

小李移動開發成長記 —— 大話小程式

傳統網站前端開發的同學初次接觸小程式,會有許多困惑:為什麼沒有div,view 是什麼、怎麼沒有 ajax,wx.request 為什麼是回撥方式、預覽怎麼要用小程式開發者工具、APPID有什麼用、安裝npm包怎麼還要構建、tabBar 是什麼、語法怎麼和vue很像但是有的部分又不同、@import 用法怎麼和 css 中不同...

本篇透過微信小程式(釋出較早,影響力較大)來介紹小程式,幫助你快速認識小程式,並解決以上困惑。主要介紹:

  1. 小程式和網站的差異
  2. 小程式和 vue 語法差異
  3. 小程式通訊模型和執行機制
  4. 三方小程式開發流程
  5. 如何新建專案,全域性和區域性配置是什麼
  6. 小程式基本語法:wxsl、wxss、js(wxs)
  7. 小程式API的Promise化
  8. 應用生命週期和頁面生命週期
  9. 小程式元件和自定義元件
  10. 小程式路由和狀態管理
  11. 分包是什麼,有什麼作用

背景

小李雖然會一些react、vue、js,但是移動端開發做的比較少,幾乎不會小程式開發。

下一階段的任務是移動端開發,涉及H5、小程式、公司內部自建的移動端的框架、除錯工具、TS等。

如何快速上手這部分工作,經過三分鐘的思考,決定出大致要加強的方向:

  • 小程式:有許多小程式的開發
  • js 基礎:程式碼要寫的優雅,比如許多 if 不是一個好習慣;不要看到別人的 Promise 就感覺生疏,別人的解構寫法是否有問題也能看出來
  • react:專案技術棧用到 react
  • 加強TS:許多程式碼有TS,否則看不懂,修改程式碼也不能透過編譯
  • 移動端開發流程:熟悉公司移動開發流程,比如模擬器、雲真機、實體機、公司的抓包工具
  • 移動端玩法:比如呼叫 jsAPI(getLocation)需要同時開啟“系統地理位置、系統授權宿主(支付寶/小程式)地理位置許可權、宿主給小程式地理位置許可權”,否則可能會彈出”地理位置許可權申請“的彈框;懸浮球的玩法;半屏展示;全屏展示頁面(即webview 擴充套件到狀態列)

認識小程式

小程式 VS 網站

小程式類似網站,只是網站在瀏覽器中開啟,而小程式透過小程式平臺(微信、支付寶)開啟。

兩者相似點

  • 跨平臺:微信小程式在微信中開啟,支付寶小程式在支付寶中開啟;網站在瀏覽器中開啟
  • 無需下載和安裝
  • 實時更新:釋出後,使用者就會自動獲取最新版本

兩者不同點

  • 執行環境:小程式的宿主是小程式平臺,例如微信、支付寶;網站執行在瀏覽器中;
  • 功能和許可權:小程式因為嵌在超級應用內(微信、支付寶),可以呼叫一些原生功能,比如支付、地理位置、攝像頭,部分功能需要使用者授權;網站受限於瀏覽器提供的API,總體上授權會更有限;
  • 體驗和效能:小程式在體驗和效能上更接近原生應用,響應更快、UI更流暢
  • 生態與流量:藉助超級應用的平臺生態,容易獲取使用者。比如微信小程式可以透過微信群、朋友圈等社交渠道快速傳播;網站透過搜尋引擎最佳化(SEO)、廣告,相對小程式,推廣難度可能大一些
  • 開發語言和工具:使用特定的框架和工具集,例如微信小程式使用WXML、WXSS、JS;網站使用標準的HTML、CSS、JS以及各種前端框架和庫(React、Vue)
  • 開發模式:網站是瀏覽器+程式碼編輯器;微信小程式:申請小程式開發賬號、安裝小程式開發者工具、建立和配置小程式專案
  • 程式碼託管:網站本地開發完提交到程式碼託管平臺(github),之後會從託管平臺部署到實際執行的伺服器上;小程式程式碼在本地編寫和除錯後,直接上傳到對應的小程式平臺,這裡涉及使用官方提供的開發者工具上傳程式碼,平臺稽核,稽核後釋出;小程式平臺負責程式碼的託管和版本控制。

微信小程式 VS Vue

有人說小程式比 Vue 簡單多了。我們來對比兩者異同,會發現小程式在語法上有許多和vue相似

相同點

  • 元件開發:微信小程式使用 wxml定義元件結構、wxss 定義樣式、js 定義邏輯、json 用於配置;Vue 使用 .vue 進行單檔案元件開發
  • 資料繫結:微信小程式透過 {{}}進行資料繫結,類似 vue.js 模板語法
  • 事件處理:微信小程式使用 bingdtap 或 catchtap 等事件繫結;vue 使用 v-on(或@) 進行事件繫結
  • 條件渲染和列表渲染:小程式使用 wx:if 和 wx:for 指令;vue 使用 v-if 和 v-for 指令

不同點

  • 執行環境:微信小程式執行在微信的容器環境中,只能在微信中使用,依賴於微信的API和平臺;vue 執行在瀏覽器和node.js中。
  • 檔案結構:微信小程式,每個元件由4個檔案組成(wxml, wxss, js, json);vue 在一個 .vue 檔案中
  • 樣式處理:微信小程式 使用wxss 進行定義,類似CSS;vue 使用標準的CSS
  • 框架特徵:微信小程式:提供了一些特定微信環境的API,例如訪問微信支付;Vue專注於UI層,提供了豐富的生態系統
  • 生態系統和擴充套件:微信小程式,由微信官方提供豐富的API,社群貢獻元件庫和開發工具;Vue 有強大的生態系統,包括大量的第三方外掛、元件庫和開發工具

宿主環境

手機微信是微信小程式的宿主環境,支付寶是支付寶小程式的宿主環境

小程式藉助宿主環境提供的能力,可以完成許多普通網頁無法完成的功能,如:微信登入、微信支付、微信掃碼、地理定位...

透過宿主環境,小程式提供的能力包含:通訊模型執行機制元件API

通訊模型

小程式通訊主體包含:渲染層邏輯層

  • wxml(類似 html) 和 wxss(類似 css) 工作在渲染層
  • js指令碼工作在邏輯層

小程式中的通訊模型分兩部分:

  • 渲染層和邏輯層通訊:由微信客戶端進行轉發
  • 邏輯層和第三方伺服器之間的通訊:由微信客戶端進行轉發
執行機制

小程式啟動過程

  1. 小程式程式碼下載到本地:使用者首次開啟或更新小程式時,微信客戶端會從遠端伺服器下載小程式的程式碼包。這個過程會根據網路狀況和程式碼包大小有所不同,微信平臺會對程式碼包進行一定的最佳化和壓縮處理以加快下載速度。
  2. 解析 app.json 全域性配置檔案:下載完成後,微信客戶端會首先解析app.json檔案,這個檔案包含了小程式的全域性配置資訊,如頁面路徑、視窗表現、網路超時時間、底部tab等。這些配置決定了小程式的基本框架和表現形式。
  3. 執行 app.js,小程式入口檔案:接下來,微信客戶端會執行app.js檔案,這是小程式的邏輯層入口。在app.js中,會呼叫App函式來建立小程式例項,並可以在這個函式中定義全域性的資料和方法,進行一些初始化操作,如註冊全域性的生命週期回撥函式(如onLaunch, onShow, onHide等)。
  4. 渲染小程式首頁:根據app.json中配置的首頁路徑,微信客戶端會載入首頁的.wxml(結構)、.wxss(樣式)和.js(邏輯)檔案,開始渲染小程式的首頁。邏輯層會透過Page函式建立頁面例項,並執行頁面的生命週期函式,如onLoad,進行資料初始化、網路請求等操作。隨後,渲染層依據邏輯層提供的資料渲染頁面內容。
  5. 小程式啟動完成:當首頁頁面渲染完成並呈現給使用者時,標誌著小程式的啟動過程結束,此時使用者可以開始與小程式進行互動。同時,小程式的不同頁面之間可以透過頁面路由進行跳轉,邏輯層與渲染層繼續根據使用者的操作進行資料更新和介面重繪。

Tip:上面是冷啟動,對於已經開啟過的小程式,再次進入可能就會有熱啟動的情況。比如程式碼下載可能就會被跳過

頁面渲染過程

  1. 載入解析頁面的 .json 配置檔案:當需要渲染某個頁面時,微信小程式框架首先會載入該頁面對應的.json配置檔案。這個檔案定義了頁面的視窗樣式、導航欄樣式等頁面級的配置資訊,這些配置會影響頁面的外觀和行為。
  2. 載入頁面的 .wxml 和 .wxss 樣式:緊接著,框架會載入頁面的結構檔案.wxml和樣式檔案.wxss。.wxml檔案定義了頁面的結構和佈局,類似於HTML;而.wxss檔案則是用來控制頁面元素樣式的,類似於CSS。這兩個檔案共同決定了頁面的外觀。
  3. 執行頁面的 .js 檔案,呼叫 Page() 建立頁面例項:之後,框架會執行頁面的邏輯檔案.js。在這個檔案中,透過呼叫Page函式來建立頁面例項,並可以在其中定義頁面的初始資料、生命週期函式(如onLoad、onShow、onHide等)、事件處理函式等。頁面的初始化資料和邏輯處理都在這個階段完成。
  4. 頁面渲染完成:當頁面的結構、樣式和資料都準備就緒後,微信小程式的渲染引擎會根據.wxml和.wxss以及頁面例項中的資料來渲染頁面。這個過程包括解析WXML模板,應用WXSS樣式,繫結資料到模板,最終生成使用者可見的介面。頁面渲染完成後,使用者就可以看到並開始與這個頁面進行互動了。
API

小程式官方把API分三類:

  • 事件監聽API:以 on 開頭,監聽某些事件。例如 wx.onWindowResize(callback)(小程式中沒有windown) 監聽視窗尺寸變化
  • 同步API:以Sync結尾的都是同步API,透過函式直接獲取,如果執行出錯會丟擲異常。例如wx.setStorageSync('key', 'value') 向本地快取寫入資料
  • 非同步API:類似$.ajax,需要透過 success、fail、cpmplete 接收呼叫的結果,例如 wx.request 發起網路資料請求,透過 success 接收呼叫的結果

小程式研發流程

小程式開發流程不同於傳統網站

傳統網站開發:vscode編寫程式碼,瀏覽器預覽效果,git提交到程式碼。

小程式開發步驟大致如下(以微信小程式三方開發為例):

  1. 申請小程式賬號,獲得 AppId(你要建立的小程式唯一標識)
  2. 透過小程式開發者工具建立專案
  3. 透過小程式開發者工具編譯預覽效果
  4. 透過小程式開發者工具把程式碼上傳到微信平臺
  5. 選擇一個開發版本作為體驗版
  6. 體驗完成申請釋出
  7. 釋出到微信平臺

Tip:一方開發通常指的是由小程式的所有者的開發,也是官方開發; 三方開發,是指由第三方開發者為小程式提供功能或服務;

小程式賬號和APPID

註冊小程式賬號,主要是為了獲得APPID。

APPID 是小程式唯一標識,用於在微信上識別和區分不同的小程式,在註冊過程中,需要填寫一些基本資訊,如小程式名稱、小程式介紹、小程式類別等。完成這些,微信會為你生成一個APPID。APPID將用於開發、釋出和運營小程式各種操作,包含開發工具的配置等

大致流程如下:

  • 點選註冊:進入微信官網(https://mp.weixin.qq.com/cgi-bin/wx),點選“註冊”
  • 註冊小程式:包含賬號資訊(郵箱、密碼...)、郵箱啟用、資訊登記(註冊國家、主體型別-個人:身份證姓名、身份證、手機、簡訊)

註冊後就可以登入到小程式後臺管理介面,在“開發”導航中就能找到APPID。

小程式開發工具

小程式你不用特定工具怎麼預覽效果?瀏覽器又不認識小程式

微信開發者工具提供如下功能:

  • 快速建立小程式專案
  • 程式碼檢視和編輯
  • 小程式進行除錯、預覽
  • 小程式釋出

找到穩定版下載安裝成功,在桌面會看到一個二維碼,用自己的微信掃一掃,登入後就能開啟“微信開發者工具”。

建立專案:可以指定專案所在目錄、後端服務是否選擇雲開發、語言有javascript或 TypeScript。

小程式工具主介面分五個部分:

  • 選單欄:如幫助(裡面有“開發者文件”)、設定、專案、工具(有構建 npm、外掛)
  • 工具欄:模擬器、編輯器、偵錯程式、編譯真機除錯
  • 模擬器:模擬微信(底部有:頁面路徑、頁面引數
  • 程式碼編輯區
  • 除錯區:console控制檯、Network、Storage
自定義編譯模式

透過小程式工具,普通編譯會從小程式首頁開始,而平時我們修改某頁面邏輯,儲存後想立刻看到效果,而不是又從首頁切換好幾次才到該頁面。這是,我們可以使用“自定義編譯條件”。

點選“普通編譯”下的“新增編譯模式”,選擇要啟動的頁面,還可以傳參,新建即可。下次就選擇這個頁面編譯即可。

一個頁面可以建立多個編譯頁面,比如有參的、無參的...

協同工作

小程式通常不是一個人完成的。

微信小程式成員管理(三方)體現在管理員對小程式專案成員及體驗成員的管理

  • 專案成員:參與開發、運營,可登入小程式後臺,管理員可新增、刪除成員,並設定成員角色
  • 體驗成員:參與小程式內測體驗、可使用體驗版小程式,不屬於專案成員,管理員及專案成員可以新增、刪除體驗成員

開發者的許可權有:

  • 開發者許可權
  • 體驗者許可權
  • 登入許可權:登入小程式後臺,無需管理員確認
  • 開發設定:設定小程式伺服器域名、訊息推送及掃描普通二維碼開啟小程式

Tip:之所以有這些角色,因為小程式的開發流程不同於網站開發,小程式的程式碼由小程式平臺管理。

小程式版本

小程式釋出流程大致如下:上傳程式碼到開發版本,多次迭代開發版本,根據開發版本生成體驗版本,驗證透過後提交稽核,稽核透過後釋出。

  • 開發版本:使用開發者工具,可將程式碼上傳到開發版本中。開發版本只保留每人最新的一份上傳的程式碼。點選提交稽核,可以將程式碼提交稽核。開發版本刪除,不影響線上版本和稽核中的版本。
  • 體驗版本:選擇某個開發版本作為體驗版
  • 稽核中版本:只能有一份程式碼處於稽核中。有稽核結果後可以釋出到線上,也可以直接重新提交稽核,覆蓋原稽核版本
  • 線上版本:線上所有使用者使用的程式碼版本

Tip:微信小程式和支付寶小程式都提供了多版本開發和管理功能。體驗版只能同時根據其中一個開發版本生成。

推廣和運營資料

釋出後就需要推廣

推廣可以基於微信碼和小程式碼。

小程式碼的優勢:

  • 樣式上更具有辨識度
  • -更加清晰樹立小程式品牌形象

小程式可以透過後臺檢視運營資料,也可以使用“小程式資料助手”(微信搜尋)檢視已釋出小程式相關資料:訪問分析、實時同級、使用者畫像...

小程式也可以使用第三方埋點工具,例如:友盟友、神策資料...

小程式對 npm 包支援和限制

微信小程式支援 NPM 包,但小程式能用的 Npm 包卻不多

下面是一些限制和注意事項:

  • API 限制:不支援依賴 node.js 內建庫、瀏覽器內建物件、C++外掛的 npm 包
  • 包大小限制:微信小程式的包大小有限制,單個包不能超過 2 MB,總體積不能超過 20 MB。因此,在使用 NPM 包時需要注意其體積,避免超出限制。
  • 構建工具:NPM 包的使用需要透過微信開發者工具進行構建和處理,確保在開發者工具中啟用了 "構建 NPM" 功能。

新建專案和配置

專案基本結構

建立一個微信小程式專案,目錄結構如下:

- pages: 存放所有小程式的頁面
- utils:存放工具性質的模組
- app.js:小程式入口檔案
- app.json:小程式全域性配置檔案。包含小程式所有頁面路徑、視窗外觀、介面表現(所有頁面的背景色、文字顏色、小程式元件所使用的樣式版本)、底部tab
- project.config.json:專案配置檔案。記錄我們對小程式開發工具做的個性化配置,如專案名、小程式賬號ID、編譯相關配置(ES6轉ES5、上傳程式碼時自動壓縮混淆、上傳程式碼時樣式自動補全)
- sitemap.json:配置小程式及其頁面是否允許被微信索引。微信現已開放了小程式內搜尋,類似網頁的SEO。

小程式官方建議所有小程式頁面都放在 pages 目錄中,以單獨資料夾存放:

- pages
  - index
    - index.js 頁面指令碼
    - index.wxml 頁面結構
    - index.wxss 頁面樣式
    - index.json 當前頁面的配置,如視窗的外觀
  - pageb
    - pageb.js
    - pageb.wxml
    - pageb.wxss
    - pageb.json

Tip:小程式中有4種json配置檔案(具體作用後面會介紹)

  • 專案根目錄中的 app.json
  • 專案根目錄中的 project.config.json
  • 專案根目錄中的 sitemap.json
  • 每個頁面資料夾中的 json

新建小程式頁面

在 app.json->pages 中新增頁面存放路徑,ctrl+s儲存,工具會自動建立對應頁面檔案。

{
  pages: [
    "pages/index/index",
    "pages/pageb/pageb",
  + "pages/pageb/pagec"
  ]
}

修改專案首頁

只需調整 app.json->pages 陣列中頁面路徑的順序,小程式會把排在第一位的頁面,當做專案首頁渲染。

全域性配置

小程式根目錄下的 app.json 是小程式全域性配置檔案。

常用配置:

  • pages 記錄當前小程式所有頁面的存放路徑
  • window 全域性設定小程式視窗外觀
  • tabBar 設定小程式底部的 tabBar 效果
  • style 是否啟用新版的元件樣式

示例:

{
  "pages": [
    "pages/index/index",
    "pages/logs/logs"
  ],
  "window": {
    "navigationBarTitleText": "小程式示例",
    "navigationBarBackgroundColor": "#ffffff",
    "navigationBarTextStyle": "black",
    "backgroundColor": "#eeeeee",
    "backgroundTextStyle": "light",
    "enablePullDownRefresh": true,
    "onReachBottomDistance": 50
  },
  "tabBar": {
    "color": "#7A7E83",
    "selectedColor": "#3cc51f",
    "borderStyle": "black",
    "backgroundColor": "#ffffff",
    "list": [
      {
        "pagePath": "pages/index/index",
        "text": "首頁",
        "iconPath": "images/icon_home.png",
        "selectedIconPath": "images/icon_home_active.png"
      },
      {
        "pagePath": "pages/logs/logs",
        "text": "日誌",
        "iconPath": "images/icon_logs.png",
        "selectedIconPath": "images/icon_logs_active.png"
      }
    ]
  },
  "style": "v2"
}
視窗

小程式視窗組成部分(從上到下):

  • navigationBar 導航欄區域:包含時間、電量、微信標題
  • background 背景區域,預設不可見,下拉才顯示
  • 頁面主體區域,用了顯示 wxml 中佈局

windown節點常用配置項:

  • navigationBarTitleText 導航欄標題文字 字串
  • navigationBarBackgroundColor 導航欄背景顏色 預設#000000,型別 HexColor
  • navigationBarTextStyle 導航欄顏色(標題、電池等顏色) 僅支援 black/white,預設 white
  • backgroundColor 視窗背景色 預設#ffffff,型別 H3xColor
  • backgroundTextStyle 下拉loading 的樣式,僅支援 dark/light,預設 dark
  • enablePullDownRefresh 是否全域性開啟下拉重新整理。預設 false。開啟後會作用於小程式每個頁面。
  • onReachBottomDistance 頁面上拉觸底時間觸發時距離底部距離,單位 px,預設 50,若無特殊需求,不建議修改。

Tip下拉重新整理,通常做法是在頁面中單獨開啟,而非在這裡全域性開啟。下拉重新整理開啟後,若要實現重新整理,還得在 onPullDownRefresh 方法中處理下來重新整理邏輯,這個方法會在使用者觸發下拉重新整理操作時被呼叫。

:模擬器不能百分之百還原真機。例如下拉重新整理,在模擬器中,下拉後,過了3秒,下拉自動合上;而在真機中,不會自動合上

tabBar

小程式中 tabBar 是導航元件。特性有:

  • 位置: 通常位於小程式介面的底部。
  • 圖示和文字: 每個 tab 都可以包含圖示和文字。
  • 選中狀態: 可以配置選中和未選中狀態下的圖示和文字顏色。
  • 頁面對映: 每個 tab 對應一個頁面路徑,點選 tab 會切換到相應的頁面。

以下是一個典型的 app.json 中 tabBar 配置示例:

{
  "tabBar": {
    "color": "#999999",
    "selectedColor": "#1c1c1b",
    "backgroundColor": "#ffffff",
    "borderStyle": "black",
    "list": [
      {
        "pagePath": "pages/home/index",
        "text": "首頁",
        "iconPath": "/images/icon_home.png",
        "selectedIconPath": "/images/icon_home_active.png"
      },
      {
        "pagePath": "pages/search/index",
        "text": "搜尋",
        "iconPath": "/images/icon_search.png",
        "selectedIconPath": "/images/icon_search_active.png"
      },
      {
        "pagePath": "pages/profile/index",
        "text": "我的",
        "iconPath": "/images/icon_profile.png",
        "selectedIconPath": "/images/icon_profile_active.png"
      }
    ]
  }
}

:tabBar 只能配置最少2個,最多5個。當渲染頂部tabBar 時,不顯示 icon,只顯示文字。說tabBar 中的頁面要放在 pages 前面,否則顯示不出。

tabBar 有6個組成部分:

  • color,tab上文字的顏色
  • selectedColor,tab文字選中時的顏色
  • backgroundColor,tabBar 背景色
  • borderStyle,tabBar 邊框顏色
  • iconPath,未選中時圖片路徑
  • selectedIconPath,選中時圖片路徑

tabBar 節點配置項:

  • position,預設 bottom,可配置 top
  • borderStyle,預設 black,僅支援 black/white
  • color,hexColor 型別
  • selectedColor,hexColor 型別
  • backgroundColor,hexColor 型別
  • list,Array,必填,最少2個,最多5個

每個 tab 項配置選項:

  • pagePath,必填,頁面路徑,頁面必須在 pages 中預先定義
  • text,必填,tab上顯示的文字
  • iconPath,未選中時圖片路徑;position 為top時不顯示 icon
  • selectedIconPath,選中時圖片路徑;position 為top時不顯示 icon

頁面配置

在小程式中,全域性配置和頁面配置可以定義頁面的外觀和行為。當全域性配置和頁面配置衝突時,確實遵循就近原則,最終效果通常以頁面配置為準。這意味著頁面特定的配置會覆蓋全域性配置。這樣可以確保頁面的定製化效果。

頁面配置中常用配置項:

  • navigationBarTitleText 導航欄標題
  • navigationBarBackgroundColor 導航欄背景顏色
  • navigationBarTextStyle 導航欄文字顏色
  • backgroundColor 頁面背景顏色
  • backgroundTextStyle 下拉loading 的樣式
  • enablePullDownRefresh 是否全域性開啟下拉重新整理
  • onReachBottomDistance 頁面上拉觸底時間觸發時距離底部距離
  • disableScroll 禁止頁面滾動
  • usingComponents 頁面使用的自定義元件列表

小程式基本語法

wxml

微信小程式的 wxml 類似網頁中的 html。支付寶小程式中是 axml。

wxml 和 html 區別

  • 標籤名稱不同(比如用 view 代替 div):
    • HTML: div、span、img、a
    • wxml: view、text、image、navigator
  • 屬性節點不同
<a href="http://www.baidu.com">百度</a>
<navigator url="http://www.baidu.com">百度</navigator>
  • 提供了類似 vue 的模板語法:資料繫結、列表渲染、條件渲染
資料繫結

在 data 中定義資料,在 wxml 中使用。例如:

Page({
  data: {
    name: '張三',
    age: 18,
    url: 'http://....png',
    randomNum: Math.random() * 10,
  }
})

用Mustache語法({{}})將變數包起來即可:

<view>{{ name }}</view>
<view>{{ randomNum > 5 ? '大於5': '小於或等於5' }}</view>

動態繫結屬性不同於 vue 的 v-bind,小程式的動態繫結屬性是直接在標籤上寫(寫法不同而已,死記即可),例如:

<image src="{{ url }}"></image>

Tip: 資料在小程式開發工具控制檯的 AppData tab中可以看到。

條件渲染

小程式和vue中條件渲染對比:

  • 語法差異:微信小程式使用 wx:if、hidden、block wx:if,vue中使用 v-if,v-show。
  • wx:if 和 v-if 類似,是真正的條件渲染
  • hidden 和 v-hsow 類似,都是透過 css 控制顯隱,元素始終存在
  • block 類似 template,一次控制多個元件的展示與隱藏,且都不會渲染成實際的 dom 元素

用法:在 wxml 中使用 wx:if、wx:elif、wx:else 標籤,在 data 中定義變數,在 wx:if 中使用變數。

<view>
  <view wx:if="{{ age > 18 }}">
    你成年了
  </view>
  <view wx:elif="{{ age < 18 }}">  你未成年
  </view>
  <view wx:else>
    你很少年
  </view>
</view>
列表渲染

小程式和vue中列表渲染對比:

  • 語法差異:微信小程式使用 wx:for、wx:key,vue中使用 v-for和:key
  • 都強調為列表渲染的每一項制定一個唯一的 key
  • vue 在列表渲染中提供了更豐富的功能
  • wx:for 和 v-for 類似,都是遍歷陣列,渲染成列表

用法:在 wxml 中使用 wx:for 標籤,在 data 中定義陣列,在 wx:for 中使用陣列。

預設當前迴圈項索引是 index,當前迴圈項是 item:

<view class="container">
  <block wx:for="{{items}}" wx:key="index">
    <view>
      <text>{{index}}: {{item}}</text>
    </view>
  </block>
</view>

Page({
  data: {
    items: ['Item 1', 'Item 2', 'Item 3']
  }
});

wx:for-item 和 wx:for-index 用於自定義變數名,使得程式碼更加清晰和可讀。

<view class="container">
  <block wx:for="{{items}}" wx:for-item="user" wx:for-index="idx" wx:key="id">
    <view>
      <text>Index: {{idx}}</text>
      <text>ID: {{user.id}}</text>
      <text>Name: {{user.name}}</text>
    </view>
  </block>
</view>

Page({
  data: {
    items: [
      { id: 1, name: 'Alice' },
      { id: 2, name: 'Bob' },
      { id: 3, name: 'Charlie' }
    ]
  }
});

: 小程式的 key,直接是迴圈項中的屬性,且不需要 {{}}。如果是vue,得透過迴圈項找到

<template v-for="item in items" :key="item.id">

wxss

小程式的樣式,類似網頁的 css。

wxss 對比 css

wxss 具備 css 大部分特定,wxss 還對 css 進行了擴充和修改,以適應小程式的開發

wxss 和 css 區別:

  • 新增 rpx(responsive pixel,響應式畫素)尺寸單位
    • css中實現響應式佈局,需要手動進行畫素轉換(常用 rem)。比如設計師提供的是 750 稿子,我們可能會將 1rem 等於75,設計稿的75就是1rem
    • wxss 在底層支援新的尺寸單位 rpx,在不同螢幕上會自動進行換算,同樣是 750 的稿子,75個大小直接寫成 75rpx 即可。
  • 提供全域性樣式和區域性樣式
    • 微信小程式:專案根目錄中 app.wxss 會作用於素有小程式頁面;區域性頁面的 .wxss 樣式僅對當前頁面生效
    • web 中CSS是全域性作用,除非使用CSS模組化工具
  • 檔案型別:微信小程式是 .wxss
  • 媒體查詢:微信小程式不支援傳統CSS媒體查詢,如@media
  • css動畫和過度:微信小程式支援部分 css 動畫和過度,但有一些限制
  • wxss 僅支援部分常見的 css屬性和選擇器:.class和#id、element、並集選擇器和後代選擇器、::after和::before等偽類選擇器
  • flex佈局:微信小程式中的 flex 大部分與css一致,但具體表現有細微差異
  • 引入樣式:微信小程式透過 @import 引入其他 .wxss,不支援 @import url() 形式引入外部 css
rpx

rpx 原理非常簡單,把所有裝置的螢幕從寬度上等分 750 份

  • 在375的裝置,1rpx 等於 0.5px
  • 在1500的裝置,1rpx 等於 2px

Tip:rem和 rpx 在實現響應式佈局中,主要關注的是寬度的自適應。高度需要自行處理,比如等比擴充套件,或者限制最高高度。

iphone 螢幕寬度是 375px(邏輯畫素),共有 750個畫素點(物理畫素),1個邏輯畫素等於2個物理畫素,等分750rpx。則:

  • 750rpx = 375px = 750 物理畫素
  • 1rpx = 0.5px = 1 物理畫素

開發舉例:根據設計稿來,有的要求是1:1,有的是1:2,寬100px200px的盒子,轉成rpx 就是 200rpx400rpx。

@import

@import 後根需要匯入的外聯樣式的相對路徑,用;表示結束。示例:

@import "demo.wxss";
.box{

}

使用時是 class 而非 className。

Tip:微信小程式支援使用 less,不過需要進行一些配置。

全域性樣式和區域性樣式

定義在 app.wxss 中的樣式是全域性樣式,作用於每一個頁面

定義在頁面的 .wxss 中的樣式是區域性樣式,只作用於當前頁面。

:當區域性樣式和全域性樣式衝突,和 css 中一樣:哪個權重高用哪個,如果權重相同,則使用就近原則(採取區域性樣式)

Tip:把滑鼠放到小程式工具中選擇器上,會有選中提示,例如:Selector Specificity:(0, 1, 0)

js

Tip:小程式中的 js 分3大類

  • app.js:小程式入口檔案,透過呼叫 App() 函式啟動整個小程式
  • 頁面.js:頁面的入口檔案,透過呼叫 Page() 函式建立並執行頁面
  • 普通.js:普通功能模組檔案,用來封裝公共的函式或屬性,供頁面使用
wxs

wxs在微信小程式中的作用類似 Vue.js中的過濾器(vue3 已廢除過濾器)

小程式中的 wxs 和 javascript 是兩種語言,區別有:

  • wxs 在檢視層中執行,js執行在邏輯層
  • wxs 隔離性。不能呼叫 js 中定義的函式,不能呼叫小程式的API
  • wxs 設計初衷為了提高資料處理效能,特別是與介面渲染密切相關場景,減少和邏輯層的通訊

Tip: 在 ios 中,小程式內的 wxs 比 js 塊 2~20倍;在安卓上無差異。

wxs的語法基於JavaScript,這意味著如果你熟悉JavaScript,學習wxs會相對容易:

  • wxs 有自己的資料型別:number、string、boolean、array、object...
  • wxs 不支援類似es6+語法,不支援let、const、解構賦值、箭頭函式;支援 var、function、es5語法
  • wxs 遵循 commonjs規範:module物件、require()函式、module.exports物件
  • wxs 可以編寫在 <wxs>標籤中,就像js寫在 <script> 中,wxs 必須提供 module 屬性,用來指定當前 wxs 模組名稱

外聯wxs用法(src必須是相對路徑):

<!-- index.wxml -->
<wxs module="utils" src="../../utils/utils.wxs"/>
<view>
  <text>{{utils.formatDate(new Date())}}</text>
</view>
// utils.wxs
module.exports = {
  formatDate: function(date) {
    var year = date.getFullYear();
    var month = date.getMonth() + 1;
    var day = date.getDate();
    return [year, month, day].map(this.formatNumber).join('-');
  },

  formatNumber: function(n) {
    n = n.toString();
    return n[1] ? n : '0' + n;
  }
};

資料請求

小程式中網路資料,處於安全考慮,小程式官方對資料介面做了如下限制:

  • 只能請求 https 型別介面
  • 必須將介面的域名新增到信任列表中

假如希望在自己的微信小程式中,希望請求https://www.xxx.com/域名下的介面。配置步驟:登入微信小程式後臺->開發->開發設定->伺服器域名->修改request合法域名。注意:

  • 域名只支援 https
  • 域名不能是 ip 地址或 localhost
  • 域名必須經過 ICP 備案
  • 伺服器域名一個月內最多可申請5次修改

Tip: 如果後端僅提供http協議介面,為不耽誤開發進度,可以在微信開發者工具中,臨時開啟「開發環境不校驗請求域名、TLS版本及HTTPS證書」,跳過 request 合法域名校驗,僅限在開發和除錯階段使用。

get和post請求

在微信小程式中,您可以使用 wx.request 方法來發起 HTTP GET 和 POST 請求。這個方法提供了一種簡單的方式來與伺服器進行資料互動:

請看示例:

wx.request({
  url: 'https://api.example.com/data',
  method: 'GET', 
  data: {
    key1: 'value1',
    key2: 'value2'
  }, 
  header: {
    'content-type': 'application/json' 
  },
  success: function(res) {
  },
  fail: function(err) {
  }
});
wx.request({
  url: 'https://api.example.com/submit', 
  method: 'POST',
  data: {
    key1: 'value1',
    key2: 'value2'
  }, 
  header: {
    'content-type': 'application/json' 
  },
  success: function(res) {
  },
  fail: function(err) {
  }
});
小程式和跨域

小程式沒有常規的跨域問題,但本質上還是涉及一些。但是對於前端開發,則無需處理跨域。

跨域(Cross-Origin Resource Sharing,簡稱 CORS)是指一個域名下的文件或指令碼嘗試請求另一個域名下的資源時,由於瀏覽器的同源策略(Same-origin policy)限制而導致的請求被阻攔的行為。這裡的“同源”指的是協議、域名和埠號完全相同。同源策略是一種安全措施,旨在防止惡意網站透過指令碼讀取另一個網站的敏感資料。

跨域的本質是指瀏覽器出於安全考慮,實施的一種同源策略(Same-origin policy)

小程式的主體不是瀏覽器,而是小程式平臺,所以沒有常規的跨域問題。

因為小程式需要配置受信任域名,其實也在一定程度上有了安全保障,小程式的服務端也會涉及到CORS的配置

小程式和Ajax

Ajax核心依賴瀏覽器中的 XMLHttpRequest 物件,而小程式的宿主環境是微信客戶端,所以小程式不叫”發起ajax請求“,而叫”發起網路請求“

微信小程式沒有直接使用 ajax 這個術語,但提供了類似非同步HTTP請求能力,主要透過 wx.request 介面來完成 Get 或 Post 請求,這一過程和Ajax非常類似,都是非同步獲取資料並更新介面而不阻塞頁面。所以小程式中不說”ajax“,但實際上具備非同步獲取資料的能力

wx.request 和 ajax 功能相似,運營環境和實現機制不同。

請看示例:

wx.request({
  url: 'https://api.example.com/data', 
  method: 'GET', 
  data: {
    key1: 'value1',
    key2: 'value2'
  }, // 請求引數
  header: {
    'content-type': 'application/json' 
  },
  success: function(res) {
  },
  fail: function(err) {
  }
});

wx.request 可以與 async/await 和 Promise.all 配合使用:

  • 封裝一個使用 wx.request 的 Promise 函式
const request = (options) => {
  return new Promise((resolve, reject) => {
    wx.request({
      ...options,
      success: res => resolve(res),
      fail: err => reject(err)
    });
  });
};
  • 然後在 async/await 中使用它:
Page({
  async onLoad() {
    try {
      const response = await request({
        url: 'https://example.com/api/data',
        method: 'GET'
      });
      console.log('Data:', response.data);
    } catch (err) {
      console.error('Error:', err);
    }
  }
});
小程式API的 Promise 化

在開發微信小程式時,許多原生 API 是基於回撥函式的,這在現代 JavaScript 程式設計中可能不太方便。為了更好地處理非同步操作,我們可以將這些回撥函式形式的 API 轉換為 Promise 形式

一種是手動封裝

一種是用庫(例如miniprogram-api-promise)。例如:
安裝,構建後,在你的專案中配置並使用:

// app.js
import wxp from 'miniprogram-api-promise';

App({
  onLaunch() {
    // 把所有 wx 函式 promise 化
    wxp.init();
  }
});

在頁面或元件中使用:

// pages/index/index.js
Page({
  data: {},

  async onLoad() {
    try {
      const response = await wx.p.request({
        url: 'https://api.example.com/data',
        method: 'GET',
      });
      console.log(response.data);
    } catch (error) {
      console.error(error);
    }
  }
});

生命週期

小程式有兩類生命週期:

  1. 應用生命週期:小程式從啟動->執行->銷燬
  2. 頁面生命週期:小程式中每個頁面的載入->渲染->銷燬

頁面的生命週期範圍小,應用程式的生命週期範圍大:
小程式啟動-> 頁面A的生命週期 -> 頁面B的生命週期 ->頁面C的生命週期 -> 小程式結束

應用生命週期

應用生命週期函式需要寫在 app.js中:

App({
  onLaunch: function(opts) {},
  onShow: function(opts){},
  hoHide: function(){},
})
  • onLaunch: 小程式啟動後立即執行,全域性只觸發一次。適合做一些初始化設定,如登入、全域性變數初始化等。
  • onShow: 小程式啟動或者從後臺進入前臺顯示時觸發。可以在這裡執行資料請求、恢復介面狀態等操作。
  • onHide: 小程式從前臺進入後臺時觸發。可以在此清理臨時資料、暫停計時器等,以節省資源。
  • onError: 捕獲小程式的異常錯誤,包括指令碼錯誤、API呼叫錯誤等,對於監控小程式執行狀態非常有用。
  • onUnhandledRejection (可選): 捕獲未處理的Promise拒絕錯誤,這是較新的API,用於增強錯誤處理能力。

Tip:微信開發者工具有一個選項“切後臺”,就可以模擬切到後臺

頁面生命週期

每個小程式頁面也有其獨立的生命週期,主要用於控制頁面的載入、渲染、顯示、隱藏和解除安裝等過程。主要生命週期包括:

  • onLoad: 頁面載入時觸發(一個頁面只呼叫一次)。適合初始化頁面資料、獲取頁面引數等。
  • onShow: 頁面顯示/切入前臺時觸發。可以在這裡設定頁面資料、響應上個頁面傳遞的引數等。
  • onReady: 頁面初次渲染完成時觸發(一個頁面只呼叫一次)。此時可以進行一些DOM操作(雖然一般推薦使用setData來改變介面)。
  • onHide: 頁面隱藏/切後臺時觸發。可以在這裡儲存頁面狀態、停止定時器等。
  • onUnload: 頁面解除安裝時觸發。適合做一些清理工作,如取消網路請求、移除事件監聽等。
  • onPullDownRefresh: 頁面下拉重新整理時觸發,需要在頁面配置中開啟enablePullDownRefresh。
  • onReachBottom: 頁面上拉觸底時觸發,用於分頁載入更多資料。
  • onPageScroll: 頁面滾動時觸發,可以用來監控頁面滾動位置。
  • onShareAppMessage: 使用者點選頁面內分享按鈕時觸發,用於自定義分享內容

Tip:後臺進入前臺,先執行全域性的 onShow,再執行頁面的 onShow。

下拉重新整理

啟用下拉重新整理有全域性開啟下拉和區域性開啟下拉,實際開發,推薦使用區域性開啟下來,也就是為需要的頁面單獨開啟下拉。

這裡說一下實現:

  • 開啟區域性頁面下拉
{
  "enablePullDownRefresh": true
}
  • 在頁面中實現下拉重新整理邏輯,注意呼叫 stopPullDownRefresh,否則真機中下拉效果一直顯示,不會主動消失。
Page({
  onPullDownRefresh: function() {
    // 這裡寫你的資料重新載入或更新邏輯
    console.log('正在重新整理...');

    // 模擬非同步資料載入過程,實際情況中可能是發起網路請求獲取新資料
    setTimeout(() => {
      // 資料載入完畢,停止下拉重新整理的動畫
      wx.stopPullDownRefresh();
      console.log('重新整理完成');
    }, 1000); // 延遲時間僅作為示例,實際應根據你的資料載入時間調整
  },

  // 頁面的其他生命週期函式和方法...
})
上拉觸底

前面提到配置中預設是距離底部50px時觸發,沒有特別要求不用改

現在要實現上拉觸底邏輯,只需要在 onReachBottom 中編碼即可:

Page({
  data: {
    itemList: [], // 初始資料列表
    page: 1,     // 當前頁數,用於分頁載入
    hasMore: true // 是否還有更多資料
  },

  onReachBottom: function() {
    // 當使用者滑動到底部時觸發此函式
    if (this.data.hasMore) {
      this.loadMoreData();
    } else {
      wx.showToast({
        title: '沒有更多資料了',
        icon: 'none'
      });
    }
  },

behaviors

小程式 behaviors 和 vue 中 mixins 類似。相似點有:

  • 都可以定義元件的屬性(properties 或 props)和資料(data)、方法
  • 都可以定義生命週期函式(微信小程式中的 lifetimes,Vue 中的生命週期鉤子函式如 created 等)

mixins 有一些問題:

  • 命名衝突:當多個 mixins 和元件本身定義了相同名稱的屬性或方法時,會導致命名衝突。Vue 會採用一種優先順序機制來決定使用哪個,但這可能導致意料之外的行為。
  • 來源不明:當檢視一個元件時,不清楚哪些屬性和方法是來自於 mixins,這會使得程式碼理解和維護變得困難。在大型專案中,特別是多個 mixins 疊加使用時,這個問題尤其明顯。
  • 耦合性:mixins 將共享邏輯放在一起,但這些邏輯可能高度依賴於元件本身的資料結構和其他邏輯,這導致了高度的耦合性,使得 mixins 難以重用和測試。

Vue 3 的組合 API(Composition API)在很多情況下可以替代 mixins,並且解決了某些 mixins 的不足之處,比如命名衝突和程式碼組織不清晰等問題

小程式 hehaviors 和 vue 中 mixins 區別:

  • 屬性和資料的合併策略:Vue 提供了比較詳細的合併策略(如陣列合並和物件覆蓋),而微信小程式的behaviors 主要是覆蓋屬性
  • 多重繼承:微信小程式的 behaviors 支援多重繼承,即一個元件可以使用多個 behaviors。Vue 的 mixins 也支援多重混入,但是在衝突解決上,Vue 的策略更為複雜和靈活

事件

事件繫結

事件是渲染層到邏輯層的通訊:事件將使用者在渲染層產生的動作,反饋到邏輯層進行處理。

小程式中常用事件:

  • tap,繫結方式是 bindtap或bind:tap,手指觸控後馬上離開,類似html中的click事件
  • input,繫結方式是 bindinput或bind:input,文字框的輸入事件
  • change,繫結方式是 bindchange或bind:change,狀態變化時觸發

在微信小程式中,推薦使用tap,而非傳統html中的 click,因為小程式為了最佳化移動端觸控體驗,特別設計了 tap 事件來處理使用者點選。相對click,有幾個優勢:

  • 移動裝置最佳化:click在移動裝置存在 300 毫秒的延遲,這是為了區分單擊和雙擊操作。而tap沒有這種延遲
  • 更好的觸控體驗:tap專為觸控式螢幕設計,更符合使用者在移動裝置上的操作習慣。

請看示例:

Page({
  data: {
    message: '按鈕尚未被點選'
  },
  // 方法不像vue需要寫在 methods 中,和 data 同級即可。
  handleTap: function (e) {
    this.setData({
      message: '按鈕被點選了!'
    });
    wx.showToast({
      title: '你點選了按鈕',
      icon: 'none'
    });
  }
});
<view class="container">
  <button bindtap="handleTap">點選我</button>
  <view class="message">{{message}}</view>
</view>

除了tap事件,小程式還提供了一些常見的觸控事件:longpress(長按)、touchstart(觸控開始)、touchemove(觸控移動)、touchend(觸控結束)、touchcancel(觸控取消)等

Tip:小程式中其他事件有

事件型別 事件 說明
觸控事件 touchstart 手指觸控動作開始
touchmove 手指觸控後移動
touchend 手指觸控動作結束
touchcancel 手指觸控動作被打斷,如來電提醒
tap 手指觸控後馬上離開
longpress 手指觸控後,超過350ms再離開
longtap 手指觸控後,超過350ms再離開(別名)
表單事件 submit 表單提交
reset 表單重置
input 輸入框輸入時觸發
focus 輸入框獲得焦點時觸發
blur 輸入框失去焦點時觸發
媒體事件 play 開始播放
pause 暫停播放
ended 播放結束
timeupdate 播放進度更新
error 播放錯誤
waiting 正在載入中
圖片事件 load 圖片載入完成時觸發
error 圖片載入錯誤時觸發
滾動事件 scroll 滾動時觸發
scrolltoupper 滾動到頂部/左邊時觸發
scrolltolower 滾動到底部/右邊時觸發
開放能力事件 contact 使用者點選客服按鈕時觸發
getuserinfo 獲取使用者資訊事件
getphonenumber 獲取使用者手機號事件
事件物件

當事件回撥觸發時,會有一個事件物件 event,其詳細屬性有:

  • type,string,事件型別。如tap,其type 就是tap
  • target,Object,觸發時間的元件的一些屬性值集合(常用
  • detail,Object,事件物件中其他屬性(額外資訊)(常用
  • currentTarget,Object,當前觸發事件的元件的一些屬性值集合
  • touches,Array,觸控事件,當前停留在螢幕中的觸控點資訊的陣列(幾個手指)
  • changedTouches,Array,觸控事件,當前變化的觸控點資訊的陣列
  • timeStamp,Integer,頁面開啟到觸發事件所經歷的毫秒數

Tip: target 和 currentTarget 的區別類似 web 中target 和 currentTarget。target 是觸發改事件的源,CurrentTarget 則是當前事件繫結的元件。比如點選 view 中的 button,e.target 是按鈕,而 e.currentTarget 是 view。

<view bind:tap="callback">
  <button>btn</button>
</view>
事件傳參

小程式事件傳參不同於 vue

在Vue中可以這麼寫:<button @click="handleClick(123)">Button 1</button>

但小程式會將 bindtap 屬性值統一當做事件名處理,相當於呼叫 handleClick(123) 的事件處理函式。

微信小程式:透過 data-* 屬性傳遞引數,使用 event.currentTarget(或target).dataset 獲取引數。請看示例:

<view class="container">
  <button data-id="1" data-name="button1" bindtap="handleTap">Button 1</button>
  <button data-id="2" data-name="button2" bindtap="handleTap">Button 2</button>
</view>

Page({
  handleTap: function(event) {
    const { id, name } = event.currentTarget.dataset;  // 獲取多個引數
    console.log('Button clicked:', id, name);
  }
});

資料同步

在微信小程式中,this.setData 是用於更新頁面資料的主要方法。當資料改變時,檢視會自動更新。this.setData 可以用來修改 Page 物件中的資料,並將資料的變化反映到介面上。

<!-- example.wxml -->
<view class="container">
  <text>計數值: {{count}}</text>
  <button bindtap="incrementCount">增加</button>
  <button bindtap="decrementCount">減少</button>
  <input placeholder="輸入內容" bindinput="handleInput"/>
  <text>輸入內容: {{inputValue}}</text>
</view>

// example.js
Page({
  data: {
    count: 0,
    inputValue: ''
  },

  // 增加計數
  incrementCount: function () {
    this.setData({
      count: this.data.count + 1
    });
  },

  // 減少計數
  decrementCount: function () {
    this.setData({
      count: this.data.count - 1
    });
  },

  // 處理輸入事件
  handleInput: function (e) {
    this.setData({
      inputValue: e.detail.value
    });
  }
});

Tip

  • 在Vue中通常直接修改資料,對於某些情況可能需要用上this.$set,但是到了 vue3 中,由於改用 proxy 響應式系統,可以自動檢測和監聽響應式屬性的新增和刪除,更加方便。
  • 小程式的 setData 和 react 中的 useState 非常相似。合併狀態都是合併,而非替換。請看示例:
Page({
  data: {
    count: 0,
    inputValue: ''
  },
  incrementCount: function () {
    this.setData({
      count: this.data.count + 1
    });
  },
  handleInput: function (e) {
    this.setData({
      inputValue: e.detail.value
    });
  }
});
文字框和資料的同步

對於文字框和資料的同步,小程式和vue實現原理類似。

vue中可以透過 v-model 實現雙向繫結,但是 v-model 的本質是 value 的屬性以及 @input 事件

<input type="text" v-model="message" placeholder="Enter text"/>
或
<input type="text" :value="message" @input="updateMessage" placeholder="Enter text"/>

new Vue({
  el: '#app',
  data: {
    message: ''
  },
  methods: {
    updateMessage(event) {
      this.message = event.target.value;
    }
  }
});

用微信小程式是這樣:

<input type="text" value="{{inputValue}}" bindinput="handleInput" placeholder="Enter text"/>


Page({
  data: {
    inputValue: '',
    errorMsg: ''
  },
  handleInput: function(event) {
    const value = event.detail.value;
    let errorMsg = '';
    if (value.length < 3) {
      errorMsg = 'Input must be at least 3 characters long';
    }
    this.setData({
      inputValue: value,
      errorMsg: errorMsg
    });
  }
});

小程式元件

小程式中的元件也由宿主環境提供,開發者可以基於元件搭建出漂亮的頁面。小程式的元件分類有:

  • 檢視容器
  • 基礎內容
  • 表單元件
  • 導航元件
  • 媒體元件
  • 地圖元件
  • canvas 畫布元件
  • 開放能力
  • 無障礙訪問

Tip: 微信小程式 vs 支付寶小程式常用元件對比。感覺幾乎相同

功能/類別 微信小程式元件 支付寶小程式元件 備註
檢視容器 view view 基本檢視容器
scroll-view scroll-view 可滾動檢視容器
swiper swiper 滑塊檢視容器
movable-view movable-view 可移動的檢視容器
cover-view cover-view 覆蓋在原生元件上的檢視容器
list 列表檢視容器
基礎內容 text text 文字標籤
icon icon 圖示元件
rich-text rich-text 富文字元件
progress progress 進度條
表單元件 form form 表單,用於收集資料
input input 單行輸入框
textarea textarea 多行輸入框
checkbox checkbox 核取方塊
radio radio 單選按鈕
switch switch 開關選擇器
slider slider 滑動選擇器
picker picker 選擇器
picker-view picker-view 嵌入頁面的滾動選擇器
label label 標籤,用於表單控制元件的說明
導航元件 navigator navigator 頁面導航
媒體元件 image image 圖片元件
video video 影片元件
audio audio 音訊元件
camera camera 相機元件
live-player live-player 實時音影片播放元件
live-pusher live-pusher 實時音影片推流元件
地圖元件 map map 地圖元件
畫布元件 canvas canvas 畫布元件,用於繪製圖形
開放能力 open-data contact-button 微信開放資料元件和支付寶客服按鈕
web-view web-view 嵌入網頁內容
ad ad 廣告元件
official-account lifestyle 微信公眾號元件和支付寶生活號元件
login button 登入按鈕(不同場景使用)
pay-button button 支付按鈕(不同場景使用)
無障礙訪問 aria-role aria-role 無障礙角色
aria-label aria-label 無障礙標籤
常用檢視容器元件
  • view,普通檢視區域,類似html中的div,是一個塊級元素,常用於實現頁面佈局
  • scroll-view, 可滾動的檢視區域
  • swiper和swiper-item,輪播圖容器元件和輪播圖 item 元件

:為什麼不用 div ,而要建立 view?
:微信小程式選擇使用 view 等自定義元件而不是原生 HTML 標籤,如 div,主要出於以下幾個原因:

  1. 框架設計:為適配小程式的架構和特性。
  2. 效能最佳化:提升移動端的渲染效能和使用者體驗。
  3. 一致性和相容性:確保在不同平臺和裝置上的一致表現。
  4. 更好地支援小程式特性:與小程式的生命週期、事件系統和樣式管理等深度整合。
  5. 方便管理和維護:提供完善的元件體系和 API,簡化開發和維護工作。
  6. 安全性:避免直接操作 DOM 帶來的安全問題。
  7. 適合移動開發:更好地適配移動端的開發和使用者體驗需求。
    透過使用 view 元件,微信小程式能夠更好地控制和最佳化應用的表現,提供更高效和一致的開發和使用者體驗。

:有了 view,為什麼還得單獨為了滾動建立 scroll-view?
:儘管 view 元件已經提供了基本的容器功能,但 scroll-view 元件作為專門的滾動容器,具有以下顯著優勢:

  1. 專為滾動設計:提供了豐富的功能和配置選項,便於控制滾動行為。
  2. 平滑滾動與效能最佳化:經過最佳化,提供更好的滾動體驗。
  3. 額外功能支援:支援彈性滾動、捲軸隱藏等移動端常見功能。
  4. 可組合性和複用性:使得程式碼更模組化、易讀和可維護。
  5. 事件監聽與處理:豐富的事件機制,便於處理滾動相關邏輯。
  6. 動態控制滾動位置:透過屬性控制滾動位置,支援動畫效果。
  7. 避免樣式衝突:確保滾動區域的獨立性和穩定性。
    總之,微信小程式引入 scroll-view 元件,是為了提供更強大、更最佳化的滾動功能,提升使用者體驗和開發效率。

:就不能將 scroll-view 合併到 view?
:儘管將 scroll-view 的功能合併到 view 元件中在理論上是可行的,但在實踐中會引入許多複雜性和技術挑戰。微信小程式選擇將 scroll-view 與 view 分開實現,是為了:

  1. 保持元件的職責單一,簡化開發和維護。
  2. 最佳化效能,提供更高效的滾動體驗。
  3. 提供豐富的功能和事件支援,增強靈活性。
  4. 避免樣式和佈局衝突,確保向下相容。
    分開實現雖然增加了學習和使用的成本,但從長期來看,能夠更好地滿足開發者和使用者的需求,同時保持程式碼的簡潔和高效。因此,微信小程式將 scroll-view 獨立出來是一個經過深思熟慮的設計選擇。
基礎內容

text: 長按選中(selectable屬性)只能使用 text,放在 view 中的不可以。

rich-text:透過其nodes 屬性節點,可以把HTML字串渲染成對應的UI結構

其他常用元件
  • button:按鈕元件,功能比html中的 button 按鈕豐富(主色調、大按鈕小按鈕、警告按鈕...),透過 open-type屬性可以呼叫微信提供的各種功能(客服、轉發、獲取使用者資訊)
  • image:圖片元件,image元件預設寬度約300px,高度約240px。mode 屬性可以用來指定圖片的裁剪和縮放,aspectFill類似 cover,aspectFit類似contain。其中差異需要自己品味
  • navigator:導航元件,類似html中的a標籤,用於頁面跳轉

自定義元件

小程式開發者工具也提供了建立元件的便捷方式,右鍵“新建 Component”

區域性元件和全域性元件

元件從引用方式分為:

  1. 區域性引用:元件只能在當前被引用的頁面中使用
  2. 全域性引用:元件每個小程式頁面都可以使用
  • 區域性引用示例:
components/
  my-component/
    my-component.wxml
    my-component.wxss
    my-component.js
    my-component.json
{
  "usingComponents": {
    "my-component": "/components/my-component/my-component"
  }
}
<view>
  <my-component text="Welcome to My Component"></my-component>
</view>
// my-component.json
{
  "component": true
}
  • 全域性引用示例:
components/
  my-global-component/
    my-global-component.wxml
    my-global-component.wxss
    my-global-component.js
    my-global-component.json

在 app.json 中進行全域性引用配置

{
  "pages": [
    "pages/index/index",
    "pages/logs/logs"
  ],
  "window": {
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#fff",
    "navigationBarTitleText": "WeChat",
    "navigationBarTextStyle": "black"
  },
  "usingComponents": {
    "my-global-component": "/components/my-global-component/my-global-component"
  }
}

頁面和元件的區別

在小程式中,頁面和元件在開發解構和使用方式上有許多相似之處,但他們用途和特性有所不同

特性 頁面(Page) 元件(Component)
功能 使用者互動的獨立檢視 可複用的功能模組或UI元素
組成檔案 .wxml, .wxss, .js, .json .wxml, .wxss, .js(呼叫Component()函式、事件需要定義到 methods中), .json(需要 "component": true
生命週期 onLoad, onShow, onReady, onHide, onUnload created, attached, ready, moved, detached
路由和導航 支援路由和導航 API 不支援路由和導航
組合和巢狀 不能巢狀在其他頁面中 可以巢狀在頁面或其他元件中
複用性 通常獨立使用 高,可在多個頁面中引用

元件樣式隔離

在微信小程式中,元件的樣式是預設隔離的。這意味著元件的樣式不會影響到外部頁面或其他元件,而外部樣式也不會影響到元件內部。這種樣式隔離機制有助於提高元件的獨立性和可複用性

如果希望外界影響到元件,也可以透過設定 `"styleIsolation" 來修改。微信小程式的樣式隔離有三種模式:

  • isolated(預設):完全隔離,元件的樣式不會影響到外部,外部的樣式也不會影響到元件內部。
  • apply-shared:元件樣式不影響外部,但外部的全域性樣式可以影響元件內部。
  • shared:元件樣式和外部樣式互相影響。

Tip:說只有class選擇器會有樣式隔離效果,id選擇器、屬性選擇器、標籤選擇器不會受樣式隔離影響

資料、方法和屬性

元件中的資料、方法和屬性,請看示例:

Component({
  properties: {
    max: {
      type: Number,
      value: 10
    }
  },
  data: {
    name: 'pjl'
  },
  methods: {
    handleFn() {
      // true
      console.log(this.data === this.properties);
      // 使用 setData 修改 properties 值
      this.setData({max: this.properties.max + 1})
    }
  }
})

Tip:說小程式中properties 屬性和 data 資料用法相同,都是可讀可寫

資料監聽

微信小程式中的 observers 和 Vue.js 中的 watch 功能相似,都是用於監聽資料變化並做出響應。然而,Vue.js 的 watch 提供了更多選項和更大的靈活性,適用於更復雜的監聽需求。微信小程式的 observers 則較為簡單和直接。

語法:

Compoment({
  observers: {
    '欄位A, 欄位B': function(欄位A的新值, 欄位B的新值) {
    }
  }
})
  • 監聽多個資料
observers: {
    'countA, countB': function(newCountA, newCountB) {
      console.log(`CountA has changed to: ${newCountA}, CountB has changed to: ${newCountB}`);
      this.setData({
        sum: newCountA + newCountB
      });
    }
)
  • 監聽物件中的多個屬性
observers: {
    'obj.v1, obj.v2': function(newFirstElement, newSecondElement) {
      console.log(`First element has changed to: ${newFirstElement}, Second element has changed to: ${newSecondElement}`);
    }
}
  • 監聽物件中所有屬性
observers: {
  'obj.**': function(newObj) {
    
  }

純資料欄位

微信小程式有純資料欄位,其主要作用:

  • 減少資料傳輸:使用 setData 方法時,所有的非純資料欄位都會被序列化併傳送到檢視層。如果某些資料僅在邏輯層使用,並且不需要渲染到檢視中,可以將這些資料標記為純資料欄位,以避免不必要的傳輸,從而提高效能
  • 狀態管理:純資料欄位可以用於儲存元件內部的一些臨時狀態或計算結果,這些狀態或結果不需要被渲染到檢視中。例如,快取一些計算結果或者維護一些內部狀態。
  • 程式碼的可維護性:標記純資料欄位可以幫助開發者更清楚地區分哪些資料是需要渲染的,哪些資料僅用於邏輯處理。這有助於提高程式碼的可讀性和可維護性。

在 options 中使用 pureDataPattern。請看示例:

Component({
  // 元件的屬性列表
  properties: {
    initialValue: {
      type: Number,
      value: 0
    }
  },

  // 元件的初始資料
  data: {
    displayResult: 0,
    __internalCache: 0 // 純資料欄位,不會被傳遞到檢視層
  },

  // 定義純資料物件的匹配模式
  options: {
    pureDataPattern: /^__/
  },

元件生命週期

  • created(常用): 元件例項被建立時觸發,此時元件的屬性值、資料等尚未初始化,不能進行資料繫結操作(即不能使用 setData 方法)。
  • attached(常用):元件例項進入頁面節點樹時觸發,可以訪問屬性值和資料,適合在這個階段進行資料繫結和初始化工作。通常用於初始化資料、監聽某些事件等。
  • ready:元件佈局完成,即檢視層的渲染已經完成,此時可以對元件的 DOM 結構進行操作。
  • moved:元件例項被移動到節點樹另一個位置
  • detached(常用):元件例項被從頁面節點樹中移除時觸發。
    適合在這個階段進行清理工作,例如取消事件監聽、清除定時器等,防止記憶體洩漏。
  • error:每當元件方法丟擲錯誤時執行

小程式元件,生命週期可以直接定義在 Component 構造器一級引數中,也可以寫在 lifetimes 欄位內(推薦方式,優先順序更高)

Component({
  // 低優先順序
  error(err) {
     
  },
  lifetimes: {
    error(err) {
     
    }
  }
});

元件在頁面的生命週期

有時,自定義元件行為依賴於頁面狀態的變化,這時就得用到元件所在頁面的生命週期。比如每當觸發頁面的 show 宣告週期時,希望重新生成一個數。

元件所在頁面的生命週期有3個:

  • show:元件所在頁面展示時觸發
  • hide:元件所在頁面隱藏時觸發
  • resize:元件所在頁面尺寸變化時觸發

例如:

Component({
  pageLifetimes: {
    show() {
      console.log('Component in page show');
      // 頁面顯示時執行的邏輯
    }
  }
});

插槽

和 vue 中類似,沒有作用域插槽。

有單個插槽和多個插槽

元件通訊

微信小程式中元件通訊,和vue中類似,父傳子用屬性,子傳父用事件。

Tip:微信小程式還有父元件透過 this.selectComponent() 獲取元件例項(應該要少用)

子元件向父元件傳遞資料示例:

// 子元件
Component({
  methods: {
    incrementCount() {
      // 觸發自定義事件,傳遞資料
      this.triggerEvent('countChange', { count: this.data.count + 1 });
    }
  }
});

<view class="my-component">
  <button bindtap="incrementCount">Increment</button>
</view>
// 父元件
<view class="container">
  <my-component bind:countChange="handleCountChange"></my-component>
</view>

Page({
  handleCountChange(e) {
    // e.detail獲取子元件傳遞的資料
    const newCount = e.detail.count;
    
  }
});

微信小程式安裝 vant weapp

vant weapp 是一套小程式UI元件庫。

小程式使用npm 包的和傳統網站有一些不同。比如:

  • 安裝和引用:傳統網站npm 包會安裝在 node_modules 目錄中;小程式開發者工具會將 node_modules 中的包處理後放在 miniprogram_npm 目錄,引用npm包時,需要使用 miniprogram_npm 路徑,例如:"miniprogram_npm/@vant/weapp/button/index"。
  • 構建:小程式需要在微信開發者工具中額外執行 “構建 NPM” 操作,將 NPM 包從 node_modules 構建到 miniprogram_npm 目錄
  • 包體積大小限制:傳統網站沒有嚴格限制包體積大小

微信小程式安裝 vant weapp,大概步驟(詳細看vant官網):

  • 透過 npm 安裝
  • 構建 npm 包
  • 修改 app.json

Tip:小程式比較特殊,每安裝一個包都得構建才能使用。建議先刪除 miniprogram_npm 這個包在構建,否則容易構建失敗等問題

路由導航

導航就是頁面中相互跳轉,瀏覽器中有 <a>location.href

vue 的單頁面中有程式設計式導航命令列導航,在微信小程式中也有程式設計式導航和命令列導航

小程式和單頁應用

先說一下傳統的單頁應用:

  • 單個HTML頁面
  • 前端路由
  • 無重新整理體驗
  • 前後端分離

微信小程式在某種程度上與單頁應用有相似的使用者體驗和部分技術實現,但在嚴格技術定義來看,它並不是單頁應用

微信小程式採用多頁面框架,每個頁面獨立存在。切換頁面的時候就可以和原生一致,可以做到滑動的效果。

小程式和單頁的相似:

  • 無重新整理體驗
  • 客戶端路由:透過客戶端的API進行頁面導航
  • 前後端分離

小程式和單頁的差異:

  • 頁面獨立:每個小程式的頁面都是獨立的,有自己的檔案和生命週期。傳統的apa則是在一個HTML檔案內動態渲染和更新內容
  • 頁面載入:小程式頁面切換時會載入相應的檔案

vue路由 vs 小程式路由

vue 中程式設計式導航和命令式導航,就像這樣:

this.$router.push({ path: '/some/path', query: { key: 'value' } });

<router-link :to="{ name: 'routeName', params: { userId: 123 } }">Go to User</router-link>

微信小程式中的命令式導航主要透過頁面的 WXML 檔案中的 <navigator> 元件實現,類似於 HTML 的 <a> 標籤。

<navigator url="/pages/somePath/somePath">Go to Some Path</navigator>
<navigator url="/pages/tabPage/tabPage" open-type="switchTab">Go to Tab Page</navigator>

微信小程式中的程式設計式導航透過 wx.navigateTo、wx.redirectTo、wx.switchTab 和 wx.reLaunch 等方法實現。這些方法允許開發者在 JavaScript 程式碼中進行頁面跳轉

// 保留當前頁面,跳轉到應用內的某個頁面
wx.navigateTo({
  url: '/pages/somePath/somePath'
});

// 關閉當前頁面,跳轉到應用內的某個頁面
wx.redirectTo({
  url: '/pages/somePath/somePath'
});

// 跳轉到 tabBar 頁面,並關閉其他所有非 tabBar 頁面
wx.switchTab({
  url: '/pages/tabPage/tabPage'
});

// 關閉所有頁面,開啟到應用內的某個頁面
wx.reLaunch({
  url: '/pages/somePath/somePath'
});
對比分析

程式設計式導航:

  • Vue Router:透過 this.$router.push 等方法進行導航,支援多種導航方式(path、name、params、query)。
  • 微信小程式:透過 wx.navigateTo、wx.redirectTo 等方法進行導航,功能豐富,但需要指定具體的 URL。

命令式導航:

  • Vue Router:透過 <router-link> 元件進行導航,語義化強,結構清晰,易讀。
  • 微信小程式:透過 <navigator> 元件進行導航,功能類似 <router-link>,但沒有 Vue 的路由命名和引數傳遞功能,需要透過 URL 進行導航。

引數傳遞:

  • Vue Router:支援透過 params 和 query 傳遞引數,非常靈活。
  • 微信小程式:引數需要拼接在 URL 中,不夠直觀,引數傳遞相對複雜。

適用場景:

  • Vue Router:適用於複雜的單頁應用(SPA),需要強大的路由管理功能和靈活的引數傳遞。
  • 微信小程式:適用於小程式開發,注重簡單和快速導航,符合小程式的設計哲學。

透過對比,可以看出 Vue Router 在單頁應用中的複雜導航管理方面更強大,而微信小程式的導航設計則更加簡潔和快速,符合小程式快速開發的需求

  1. 程式設計式導航:Vue Router 和微信小程式都提供了強大的程式設計式導航功能,前者透過 this.$router.push 等方法,後者透過 wx.navigateTo 等方法。Vue Router 更加靈活,引數傳遞更方便;微信小程式的程式設計式導航功能比較簡單,需指定具體 URL。
  2. 命令式導航:Vue Router 使用 <router-link>,微信小程式使用 <navigator>。兩者功能類似,都是用於宣告式地定義導航結構,但 Vue Router 提供了更強大的路由命名和引數傳遞功能。

宣告式導航

  • 導航到tabBar頁面: url 必須以 / 開頭;open-type表示跳轉方式,必須為 switchTab。請看示例:
<navigator url="/pages/page1/page1" open-type="switchTab">導航到page1</navigator>
  • 導航到非tabBar頁面:url 必須以 / 開頭;open-type表示跳轉方式,必須為 navigate(可省略)。請看示例:
<navigator url="/pages/page1/page1" open-type="navigate">導航到page1</navigator>
  • 後退導航,比如後退上一頁或多級頁面:open-type必須是 navigateBack,表示後退導航;delta 必須是數字(預設是1,可省略),表示後退層級。請看示例:
<navigator open-type="navigateBack" delta="1">返回上一頁</navigator>

程式設計式導航

  • 導航到 tabBar 頁面:呼叫 wx.switchTab(Object obj)。obj 中屬性有:url(必填,路徑後不能帶引數)、success、fail、complete
wx.switchTab({
  url: '/pages/tabBar/home/home',
  success: function(res) {
    // 成功回撥
  },
  fail: function(err) {
    // 失敗回撥
  }
});
  • 導航到非 tabBar 頁面:呼叫 wx.navigateTo(Object obj)。obj 中屬性有:url(必填,路徑後能帶引數)、success、fail、complete
wx.navigateTo({
  url: '/pages/page1/page1',
  success: function(res) {
    // 成功回撥
  },
  fail: function(err) {
    // 失敗回撥
  }
});
  • 後退導航:呼叫 wx.navigateBack(Object obj)。obj 中屬性有:delta(預設是1,可省略)、success、fail、complete
wx.navigateBack({
  delta: 1,
  success: function(res) {
    // 成功回撥
  },
  fail

導航傳參

  • 宣告式導航傳參:直接寫在後面
<navigator url="/pages/page1/page1?name=pjl&age=18">導航到page1</navigator>
  • 程式設計式導航傳參
wx.navigateTo({
      url: '/pages/detail/detail?itemId=123&itemName=ExampleItem'
    });

新頁面接收引數:

Page({
  onLoad: function(options) {
    // options 物件包含了傳遞的引數
    console.log(options.itemId); // 輸出: 123
    console.log(options.itemName); // 輸出: ExampleItem
  }
});

狀態管理

全域性資料共享有:vuex、mobx、Redux等

小程式中可以使用 mobx 管理小程式狀態。大概步驟:

  • 安裝 MobX 和 MobX 的微信小程式支援庫 mobx-miniprogram 和 mobx-miniprogram-bindings
  • 構建 npm 包
  • 建立 Mobx store:在專案根目錄下建立一個 store 資料夾,然後在裡面建立 index.js 檔案,定義你的 MobX store
// store/index.js
import { observable, action } from 'mobx-miniprogram';

export const store = observable({
  // 定義狀態
  count: 0,

  // 定義計算屬性
  get doubleCount() {
    return this.count * 2;
  },

  // 定義動作
  increment: action(function() {
    this.count += 1;
  }),
  decrement: action(function() {
    this.count -= 1;
  })
});
  • 將 Store 注入小程式

  • 使用 MobX 繫結頁面:在頁面中使用 mobx-miniprogram-bindings 庫來繫結 MobX store

// pages/index/index.js
import { createStoreBindings } from 'mobx-miniprogram-bindings';
import { store } from '../../store';

Page({
  // 初始化 Store Bindings
  onLoad() {
    this.storeBindings = createStoreBindings(this, {
      store,
      fields: ['count', 'doubleCount'],
      actions: ['increment', 'decrement']
    });
  },

  // 銷燬 Store Bindings
  onUnload() {
    this.storeBindings.destroyStoreBindings();
  }
});

通常建議每個頁面都有自己的 Store

全域性store和頁面store混合使用也是一種很好的實踐。

分包

小程式中的分包(subpackage)是指將小程式的程式碼分割成多個子包(subpackage),每個子包可以獨立開發、測試、釋出,最終合併成一個完整的小程式

分包的優點

  • 透過將小程式的資源按需載入,可以減少首次載入時的資源量,提高啟動速度。
  • 多團隊共同開發,解耦協作

分包型別

分包中三種包:

  • 主包(Main Package):小程式的核心包,包括小程式的入口檔案(如 app.js、app.json 和 app.wxss)以及小程式根目錄下的資源。主包在小程式啟動時載入。
  • 分包(Subpackage):除了主包之外的其他包,按需載入。可以包含頁面、元件及其他資源。
  • 獨立分包(Independent Subpackage):一種特殊的分包形式,獨立分包可以獨立於主包執行,適用於需要快速啟動的小程式模組。

分包載入規則

分包後,小程式專案:1個主包+多個分包

  • 主包:通常只包含專案啟動頁面或Tabbar頁面、以及所有分包需要的公共資源
  • 分包:只包含當前分包的頁面和私有資源(圖片、js、wxss、wxs...)

小程式啟動時,預設下載主包並啟動主包內頁面,當使用者進入分包某頁面時,客戶端會把對應分包下載下來後再展示

分包配置

假設我們有一個主包和兩個分包 subpackageA 和 subpackageB。

專案目錄結構如下:

├── app.js
├── app.json
├── app.wxss
├── pages
│   ├── index
│   └── logs
├── subpackageA
│   ├── pages
│   │   ├── pageA1
│   │   │   ├── pageA1.js
│   │   │   ├── pageA1.json
│   │   │   ├── pageA1.wxml
│   │   │   └── pageA1.wxss
│   │   ├── pageA2
│   │       ├── pageA2.js
│   │       ├── pageA2.json
│   │       ├── pageA2.wxml
│   │       └── pageA2.wxss
├── subpackageB
│   ├── pages
│   │   ├── pageB1
│   │   │   ├── pageB1.js
│   │   │   ├── pageB1.json
│   │   │   ├── pageB1.wxml
│   │   │   └── pageB1.wxss
│   │   ├── pageB2
│   │       ├── pageB2.js
│   │       ├── pageB2.json
│   │       ├── pageB2.wxml
│   │       └── pageB2.wxss

在 app.json 中配置分包資訊配置(subPackages)如下:

// app.json
{
  "pages": [
    "pages/index/index",
    "pages/logs/logs"
  ],
  "subPackages": [
    {
      "root": "subpackageA",
      "pages": [
        "pages/pageA1/pageA1",
        "pages/pageA2/pageA2"
      ]
    },
    {
      "root": "subpackageB",
      "pages": [
        "pages/pageB1/pageB1",
        "pages/pageB2/pageB2"
      ]
    }
  ]
}

Tip:分包的體積是有一定限制的,分包體積可以在“小程式開發者工具”中檢視。

打包原則

  • 小程式會安裝 subpackages 的配置進行分包,subpackages之外的目錄會被打包到主包中
  • tabBar 頁面必須在主包內
  • 分包直接不能相互巢狀

分包引用規則

  • 分包可以引用主包內公共資源
  • 主包不能引用分包內私有資源
  • 分包之間不能相互引用私有資源

獨立分包

獨立分包是微信小程式提供的一種特殊分包形式,允許某些分包獨立於主包執行。這對於需要快速啟動的模組尤其有用,例如登入模組、功能獨立的外掛模組等。使用獨立分包可以顯著提高小程式的啟動速度和使用者體驗。

獨立分包的特點:

  • 獨立執行:獨立分包無需載入主包即可啟動,具有獨立的入口檔案(如 app.js、app.json、app.wxss)。
  • 快速啟動:由於獨立分包不依賴主包,可以顯著提高這些模組的啟動速度,適用於需要快速啟動的場景。
  • 資源隔離:獨立分包的資源相對主包和其他分包是隔離的,適用於功能比較獨立的模組。

將分包配置成獨立分包,只需要一個配置:independent。請看示例

// app.json
{
  "pages": [
    "pages/index/index",
    "pages/logs/logs"
  ],
  "subPackages": [
    {
      "root": "subpackageA",
      "pages": [
        "pages/pageA1/pageA1",
        "pages/pageA2/pageA2"
      ],
      "independent": true
    }
  ]
}

分包預下載

分包預下載:是指進入小程式某頁面時,框架自動下載可能需要的包。

例如進入 tabBar pageB 頁面時下載 packageA。

透過 preloadRule 配置。就像這樣:

{
  "pages": [
    "pages/pageA/index",
    "pages/pageB/index"
  ],
  "tabBar": {
    "list": [
      {
        "pagePath": "pages/pageB/index",
        "text": "PageB"
      }
    ]
  },
  "subPackages": [
    {
      "root": "packageA/",
      "pages": [
        "pageC/index"
      ]
    }
  ],
  "preloadRule": {
    "pages/pageB/index": {
      // wifi、2g、3g、4g。wifi 不包含 2g。
      "network": "all",
      "packages": ["packageA"]
    }
  }
}

相關文章