微信小程序入門總結(jié)

一、目錄結(jié)構(gòu)

目錄結(jié)構(gòu)

1.1 主體(app)

app.js、app.jsonapp.wxss組成,包括小程序的注冊、全局配置、頁面注冊、公共變量和方法,還有樣式。

1.1.1 注冊小程序

每個小程序都需要在 app.js 中調(diào)用 App() 方法注冊小程序?qū)嵗?,綁定生命周期回調(diào)函數(shù)、錯誤監(jiān)聽和頁面不存在監(jiān)聽函數(shù)等。整個小程序只有一個 App 實例,是全部頁面共享的。

App({
  onLaunch: function () {},
  onShow: function () {},
  onHide: function () {},
  globalData: {
    appName: '',
    tplId: {},
    APPID: '',
    domain: '',
    userInfo: null,
    userWXInfo: null
  }
})

開發(fā)者可以通過 getApp() 方法獲取到全局唯一的 App 實例,獲取App上的數(shù)據(jù)或調(diào)用開發(fā)者注冊在 App 上的函數(shù)。

const appInstance = getApp()
console.log(appInstance.globalData.userInfo)

1.1.2 小程序全局配置

小程序根目錄下的 app.json 文件用來對微信小程序進(jìn)行全局配置,決定頁面文件的路徑、窗口表現(xiàn)、設(shè)置網(wǎng)絡(luò)超時時間、設(shè)置多 tab 等。

{
  "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,
  "navigateToMiniProgramAppIdList": [
    "wxe5f52902cf4de896"
  ]
}

1.2 頁面(Page)

一個小程序頁面由四個文件組成,分別是:index.js、index.wxml、index.json、index.wxss。

??為了方便開發(fā)者減少配置項,描述頁面的四個文件必須具有相同的路徑與文件名。

1.2.1 WXML

WXML(WeiXin Markup Language)是框架設(shè)計的一套標(biāo)簽語言,結(jié)合基礎(chǔ)組件、事件系統(tǒng),可以構(gòu)建出頁面的結(jié)構(gòu)。具有數(shù)據(jù)綁定、列表渲染、條件渲染模板引用等能力。

1.2.1.1 數(shù)據(jù)綁定

WXML 中的動態(tài)數(shù)據(jù)均來自對應(yīng) Page 的 data。語法使用大家熟悉的Mustache,比如:

<view>{{ message }}</view>

Page({
  data: {
    message: 'Hello,World'
  }
})

更新數(shù)據(jù)需要用到Page原型鏈上的setData函數(shù)

this.setData({
  message: 'updating view'
})
1.2.1.2 列表渲染

在組件上可以使用wx:for綁定一個數(shù)組,來循環(huán)渲染該組件。使用 wx:for-item 可以指定數(shù)組當(dāng)前元素的變量名,使用 wx:for-index 可以指定數(shù)組當(dāng)前下標(biāo)的變量名。比如:

<view wx:for="{{ array }}">
  {{ index }}:{{ item.message }}
</view>
<view wx:for="{{ array }}" wx:for-index="idx" wx:for-item="itemName">
  {{ idx }}:{{ itemName.message }}
</view>
Page({
  data: {
    array: [{
      message: 'foo',
    }, {
      message: 'bar'
    }]
  }
})

如果列表中項目的位置會動態(tài)改變或者有新的項目添加到列表中,并且希望列表中的項目保持自己的特征和狀態(tài)(如 input 中的輸入內(nèi)容,switch 的選中狀態(tài)),需要使用 wx:key 來指定列表中項目的唯一的標(biāo)識符。

wx:key 的值以兩種形式提供:

  1. 字符串:代表在 for 循環(huán)的 array 中 item 的某個 property,該 property 的值需要是列表中唯一的字符串或數(shù)字,且不能動態(tài)改變。

  2. 保留關(guān)鍵字 *this 代表在 for 循環(huán)中的 item 本身,這種表示需要 item 本身是一個唯一的字符串或者數(shù)字。

1.2.1.3 條件渲染

在框架中,使用 wx:if="" 來判斷是否需要渲染該代碼塊

<view wx:if="{{ length > 5 }}">1</view>
<view wx:elif="{{ length > 2 }}">2</view>
<view wx:else>3</view>
1.2.1.4 模板

WXML提供模板(template),可以在模板中定義代碼片段,然后在不同的地方調(diào)用。

<!--
  index: int
  msg: string
  time: string
-->
<template name="msgItem">
  <view>
    <text>{{ index }}: {{ msg }}</text>
    <text>Time: {{ time }}</text>
  </view>
</template>

使用 is 屬性,聲明需要的使用的模板,然后將模板所需要的 data 傳入,如:

<template is="msgItem" data="{{ ...item }}"/>
Page({
  data: {
    item: {
      index: 0,
      msg: 'this is a template',
      time: '2020-09-11'
    }
  }
})

注意:模板擁有自己的作用域,只能使用 data 傳入的數(shù)據(jù)以及模板定義文件中定義的 <wxs /> 模塊。

1.2.1.5 引用

WXML 提供兩種文件引用方式importinclude。

import

import 有作用域的概念,即只會 import 目標(biāo)文件中定義的 template,而不會 import 目標(biāo)文件 import 的 template。

<!-- A.wxml -->
<template name="A">
  <text> A template </text>
</template>

<!-- B.wxml -->
<import src="a.wxml"/>
<template name="B">
  <text> B template </text>
</template>

<!-- C.wxml -->
<import src="b.wxml"/>
<template is="A"/>  <!-- Error! Can not use tempalte when not import A. -->
<template is="B"/>

include

include 可以將目標(biāo)文件除了 <template/> <wxs/> 外的整個代碼引入,相當(dāng)于是拷貝到 include 位置,如:

<!-- index.wxml -->
<include src="header.wxml"/>
<view> body </view>
<include src="footer.wxml"/>

<!-- header.wxml -->
<view> header </view>

<!-- footer.wxml -->
<view> footer </view>

1.2.2 JS

頁面文件夾下的.js文件里面是頁面的腳本代碼,通過調(diào)用Page方法注冊頁面,在方法內(nèi)可指定頁面的初始數(shù)據(jù)、生命周期函數(shù)、事件處理方法等。

?? 小程序腳本邏輯運行在JSCore中,JSCore沒有dom環(huán)境,因此小程序完全不支持dom操作

1.2.3 WXSS

頁面文件夾下的.wxss文件里面是頁面的樣式表

1.2.4 JSON

每一個小程序頁面也可以使用同名 .json 文件來對本頁面的窗口表現(xiàn)進(jìn)行配置,頁面中配置項會覆蓋 app.jsonwindow 中相同的配置項。

二、生命周期

2.1 APP生命周期

APP生命周期

首次(小程序沒有運行在后臺)打開小程序,觸發(fā)且只觸發(fā)一次onLaunch方法。
小程序初始化完成后,觸發(fā)onShow方法。
小程序切換到后臺,觸發(fā)onHidden方法。
小程序從后臺切換到前臺,觸發(fā)onShow方法。
小程序代碼出錯,觸發(fā)onError方法。
小程序要跳轉(zhuǎn)的頁面不存在,觸發(fā)onPageNotFound方法。
小程序進(jìn)入后臺一定時間,或者系統(tǒng)資源占用過高,會被銷毀。

2.2 頁面生命周期

頁面生命周期

打開Page頁面,頁面初始化,觸發(fā)onLoad方法。
頁面初始化完成,進(jìn)入前臺展示,觸發(fā)onShow方法。
首次渲染頁面完畢,觸發(fā)onReady方法,一個頁面只會觸發(fā)一次。
小程序切換到后臺或者跳轉(zhuǎn)到其他頁面時,觸發(fā)onHide方法。
小程序從后臺切換到前臺或者從其他頁面返回本頁面時,觸發(fā)onShow方法。
使用wx.redirectTo()或wx.navigateBack()等重定向方法銷毀頁面時,觸發(fā)onUnload方法。

2.3 app生命周期影響page生命周期

生命周期

小程序初始化完成觸發(fā)App的onShow方法后,Page開始加載并只觸發(fā)一次Page的onLoad方法。
小程序切換到后臺時,先觸發(fā)Page的onHide方法再觸發(fā)App的onHide方法。
小程序從后臺進(jìn)入到前臺時,先執(zhí)觸發(fā)App的onShow方法再觸發(fā)Page的onShow方法

三、路由與通信

3.1 頁面路由

在小程序中所有頁面的路由全部由框架進(jìn)行管理。

開發(fā)者可以使用 getCurrentPages() 函數(shù)獲取當(dāng)前頁面棧。

路由方式 頁面棧表現(xiàn) 跳轉(zhuǎn)方式
初始化 新頁面入棧 打開小程序
打開新頁面 新頁面入棧 使用wx.navigateTo方法或<navigator opten-type="navigateTo"/>組件
頁面重定向 當(dāng)前頁面出棧,新頁面入棧 使用wx.redirectTo方法或<navigator opten-type="redirectTo"/>組件
頁面返回 頁面不斷出棧,直到目標(biāo)返回頁 使用wx.navigateBack方法或<navigator opten-type="navigateBack"/>組件或點擊左上角返回按鈕
Tab 切換 頁面全部出棧,只留下新的 Tab 頁面 使用wx.switchTab方法或<navigator opten-type="switchTab"/>組件或點擊tab按鈕
重加載 頁面全部出棧,只留下新的頁面 使用wx.reLaunch方法或<navigator opten-type="reLaunch"/>組件

wx.navigateTo():保留當(dāng)前頁面,跳轉(zhuǎn)到應(yīng)用內(nèi)除了tabbar頁面外的其他某個頁面。

wx.redirectTo():關(guān)閉當(dāng)前頁面,跳轉(zhuǎn)到應(yīng)用內(nèi)除了tabbar頁面外的其他某個頁面。

wx.navigateBack():關(guān)閉當(dāng)前頁面,返回上一頁面或多級頁面。

wx.switchTab():跳轉(zhuǎn)到tabBar頁面,并關(guān)閉其他所有非tabBar頁面。

wx.reLaunch():關(guān)閉所有頁面,打開到應(yīng)用內(nèi)的某個頁面。

頁面棧

  • wx.navigateTo()方法會增加頁面棧層數(shù),直到頁面棧為十層。
  • wx.redirectTo()方法不會增加頁面棧層數(shù)。
  • wx.navigateBack()方法會減少頁面棧層數(shù),直到頁面棧層數(shù)為一。
  • wx.switchTab()和wx.reLaunch()方法會將頁面棧層數(shù)變?yōu)橐弧?/li>
  • 可以在小程序頁面中通過getCurrentPages()方法獲取頁面棧,獲取到的第一個元素為首頁,最后一個元素為當(dāng)前頁。
  • 小程序中頁面棧最多十層。
  • 不要嘗試修改頁面棧,會導(dǎo)致路由以及頁面狀態(tài)錯誤。
  • 不要在App.onLaunch的時候調(diào)用getCurrentPages(),此時 page 還沒有生成。

3.2 頁面通信

小程序頁面之間的通信有三種方式:全局變量、本地存儲、url傳參。

全局變量: globalData

本地存儲: 將數(shù)據(jù)存儲在本地緩存中指定的key中,除非用戶主動刪除或因存儲空間原因被系統(tǒng)清理,否則數(shù)據(jù)都一直可用,且不管是在app.js還是在其他page文件的js中都可對本地存儲進(jìn)行增刪改查。

url傳參:navigator組件的url參數(shù)內(nèi),需要跳轉(zhuǎn)的頁面路徑可用“?”后接參數(shù),參數(shù)鍵與參數(shù)值用“=”相連,不同參數(shù)用“&”分隔。其他組件可以用data-“參數(shù)名”格式綁定屬性,js內(nèi)可用event.currentTarget.dataset.“參數(shù)名”的格式獲取參數(shù)值,然后使用js跳轉(zhuǎn)方法,方法的ur參數(shù)內(nèi)跳轉(zhuǎn)路徑用“?”連接跳轉(zhuǎn)參數(shù)。

參數(shù)接收: 跳轉(zhuǎn)后的頁面在onLoad生命周期函數(shù)中可以接收一個參數(shù),該參數(shù)以json的形式接收url跳轉(zhuǎn)傳遞的值

Page({
    onLoad: function(options) {
        console.log(options)
    }
})

四、常用功能

4.1 小程序登錄

小程序登錄
  1. 調(diào)用 wx.login() 獲取 臨時登錄憑證code ,并回傳到開發(fā)者服務(wù)器。
  2. 調(diào)用 auth.code2Session 接口,換取 用戶唯一標(biāo)識 OpenID會話密鑰 session_key。

4.2 UnionID 機制說明

如果開發(fā)者擁有多個移動應(yīng)用、網(wǎng)站應(yīng)用、和公眾帳號(包括小程序),可通過 UnionID 來區(qū)分用戶的唯一性,因為只要是同一個微信開放平臺帳號下的移動應(yīng)用、網(wǎng)站應(yīng)用和公眾帳號(包括小程序),用戶的 UnionID 是唯一的。換句話說,同一用戶,對同一個微信開放平臺下的不同應(yīng)用,UnionID是相同的。

4.3 獲取手機號

獲取微信用戶綁定的手機號,需先調(diào)用wx.login接口。

因為需要用戶主動觸發(fā)才能發(fā)起獲取手機號接口,所以該功能不由 API 來調(diào)用,需用 button 組件的點擊來觸發(fā)。

<button open-type="getPhoneNumber" bindgetphonenumber="getPhoneNumber"></button>
Page({
  getPhoneNumber (e) {
    console.log(e.detail.errMsg)
    console.log(e.detail.iv)
    console.log(e.detail.encryptedData)
  }
})

4.4 分享轉(zhuǎn)發(fā)

通過給 button 組件設(shè)置屬性 open-type="share",可以在用戶點擊按鈕后觸發(fā) Page.onShareAppMessage 事件:

<button open-type="share"></button>

4.5 授權(quán)

獲取用戶授權(quán): 開發(fā)者可以使用wx.getSetting獲取用戶當(dāng)前的授權(quán)狀態(tài)。

打開設(shè)置頁面: 開發(fā)者可以使用wx.openSetting打開設(shè)置界面,引導(dǎo)用戶開啟授權(quán)。

提前發(fā)起授權(quán)請求: 開發(fā)者可以使用wx.authorize在調(diào)用需授權(quán) API 之前,提前向用戶發(fā)起授權(quán)請求。

常用授權(quán)接口:

scope 對應(yīng)接口 描述
scope.userInfo wx.getUserInfo 用戶信息
scope.userLocation wx.getLocation, wx.chooseLocation 地理位置
scope.userLocationBackground wx.startLocationUpdateBackground 后臺定位
scope.address wx.chooseAddress 通訊地址
scope.invoiceTitle wx.chooseInvoiceTitle 發(fā)票抬頭
scope.invoice wx.chooseInvoice 獲取發(fā)票
scope.werun wx.getWeRunData 微信運動步數(shù)
scope.record wx.startRecord 錄音功能
scope.writePhotosAlbum wx.saveImageToPhotosAlbum, wx.saveVideoToPhotosAlbum 保存到相冊
scope.camera camera組件 攝像頭
  • 如果用戶未接受或拒絕過此權(quán)限,會彈窗詢問用戶,用戶點擊同意后方可調(diào)用接口;
  • 如果用戶已授權(quán),可以直接調(diào)用接口;
  • 一旦用戶明確同意或拒絕過授權(quán),其授權(quán)關(guān)系會記錄在后臺,直到用戶主動刪除小程序。
  • 如果用戶已拒絕授權(quán),則不會出現(xiàn)彈窗,而是直接進(jìn)入接口 fail 回調(diào)。請開發(fā)者兼容用戶拒絕授權(quán)的場景。

?? 注意:

  1. wx.authorize({scope: "scope.userInfo"}),不會彈出授權(quán)窗口,請使用<button open-type="getUserInfo" />
  2. 需要授權(quán) scope.userLocation、scope.userLocationBackground 時必須配置地理位置用途說明。

4.6 獲取系統(tǒng)信息

小程序可以使用wx.getSystemInfo()方法獲取系統(tǒng)信息。

wx.getSystemInfo({
  success (res) {
    console.log(res.model)
    console.log(res.pixelRatio)
    console.log(res.windowWidth)
    console.log(res.windowHeight)
    console.log(res.language)
    console.log(res.version)
    console.log(res.platform)
  }
})

wx.getSystemInfoSync()為wx.getSystemInfo()的同步版本。

4.7 獲取圖片

小程序可以使用wx.chooseImage()方法獲取圖片,來源可以選擇系統(tǒng)相冊或相機拍照。

wx.chooseImage({
  count: 1,
  sizeType: ['original', 'compressed'],
  sourceType: ['album', 'camera'],
  success (res) {
    // tempFilePath可以作為img標(biāo)簽的src屬性顯示圖片
    const tempFilePaths = res.tempFilePaths
  }
})

wx.chooseImage()方法獲取到的文件路徑為本地臨時路徑,需要將文件長期保存需要調(diào)用wx.saveFile()方法。

wx.chooseImage({
  success: function(res) {
    const tempFilePaths = res.tempFilePaths
    wx.saveFile({
      tempFilePath: tempFilePaths[0],
      success (res) {
        const savedFilePath = res.savedFilePath
      }
    })
  }
})

4.8 掃碼

小程序使用wx.scanCode()方法可以調(diào)起客戶端掃碼界面進(jìn)行掃碼

// 允許從相機和相冊掃碼
wx.scanCode({
  success (res) {
    console.log(res)
  }
})

// 只允許從相機掃碼
wx.scanCode({
  onlyFromCamera: true,
  success (res) {
    console.log(res)
  }
})

五、其他開發(fā)事項

5.1 原生組件

小程序中的部分組件是由客戶端創(chuàng)建的原生組件,這些組件有:

由于原生組件脫離在 WebView 渲染流程外,因此在使用時有以下限制:

  • 原生組件的層級是最高的,所以頁面中的其他組件無論設(shè)置 z-index 為多少,都無法蓋在原生組件上。后插入的原生組件可以覆蓋之前的原生組件。
  • 原生組件無法在picker-view組件中使用?;A(chǔ)庫 2.4.4 以下版本,原生組件不支持在 scroll-view、swiper、movable-view 中使用。
  • 部分CSS樣式無法應(yīng)用于原生組件,例如:無法對原生組件設(shè)置CSS動畫;無法定義原生組件為 position:fixed;不能在父級節(jié)點使用overflow:hidden來裁剪原生組件的顯示區(qū)域。
  • 原生組件的事件監(jiān)聽不能使用bind:eventname的寫法,只支持bindeventname。原生組件也不支持catch和capture的事件綁定方式。
  • 原生組件會遮擋vConsole彈出的調(diào)試面板。在工具上,原生組件是用web組件模擬的,因此很多情況并不能很好的還原真機的表現(xiàn),建議在使用到原生組件時盡量在真機上進(jìn)行調(diào)試。

為了解決原生組件層級最高的限制。小程序?qū)iT提供了 cover-viewcover-image 組件,可以覆蓋在部分原生組件上面。這兩個組件也是原生組件,但是使用限制與其他原生組件有所不同。

可覆蓋的原生組件包括 map、video、canvas、camera、live-player、live-pusher
只支持嵌套 cover-view、cover-image、button。組件屬性的長度單位默認(rèn)為px,2.4.0起支持傳入單位(rpx/px)。

5.2 分包

某些情況下,開發(fā)者需要將小程序劃分成不同的子包,在構(gòu)建時打包成不同的分包,用戶在使用時按需進(jìn)行加載。

在構(gòu)建小程序分包項目時,構(gòu)建會輸出一個或多個分包。每個使用分包小程序必定含有一個主包。所謂的主包,即放置默認(rèn)啟動頁面/TabBar 頁面,以及一些所有分包都需用到公共資源/JS 腳本;而分包則是根據(jù)開發(fā)者的配置進(jìn)行劃分。

在小程序啟動時,默認(rèn)會下載主包并啟動主包內(nèi)頁面,當(dāng)用戶進(jìn)入分包內(nèi)某個頁面時,客戶端會把對應(yīng)分包下載下來,下載完成后再進(jìn)行展示。

目前小程序分包大小有以下限制:

  • 整個小程序所有分包大小不超過 16M
  • 單個分包/主包大小不能超過 2M

對小程序進(jìn)行分包,可以優(yōu)化小程序首次啟動的下載時間,以及在多團(tuán)隊共同開發(fā)時可以更好的解耦協(xié)作。

開發(fā)者通過在 app.json subpackages 字段聲明項目分包結(jié)構(gòu):

{
  "pages":[
    "pages/index",
    "pages/logs"
  ],
  "subpackages": [
    {
      "root": "packageA",
      "pages": [
        "pages/cat",
        "pages/dog"
      ]
    }, {
      "root": "packageB",
      "name": "pack2",
      "pages": [
        "pages/apple",
        "pages/banana"
      ]
    }
  ]
}

六、參考

https://developers.weixin.qq.com/miniprogram/dev/api/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容