微信小程式開發基礎(一)「配置」與「邏輯層」

IDreamo發表於2019-05-25

微信小程式作為微信生態重要的一環,在實際生活、工作、商業中的應用越來越廣泛。想學習微信小程式開發的朋友也越來越多,本文將在小程式框架的基礎上就微信小程式專案開發所必需的基礎知識及語法特點進行了詳細總結和闡述,包括配置、函式、語法、事件及其處理、資料繫結、模組、樣式等。想開發小程式,這些內容是必須掌握的。

全文知識結構預覽:

一、程式配置:

    1、全域性配置;2、頁面配置

二、邏輯層:

    1、程式註冊:App()方法;2、頁面註冊:Page()方法;3、模組與呼叫;4、微信原生API

三、檢視層(將在單獨文章中闡述)


 一、程式配置

1、全域性配置

先來看一個典型的全域性配置app.jason檔案內容:

{
    "pages":[
        "pages/index/index",
        "pages/logs/logs"
    ],
    "window":{
        "navigationBarTitleText":"Demo",
        "navigationBarTextStyle": "black"
    },
    "tabBar":{
        "list":[{
            "pagePath":"pages/index/index",
            "text":"首頁"
            },{
            "pagePath":"pages/logs/logs",
            "text":"日誌"
            }]
    },
    "networkTimeout":{
        "request":10000,
        "downloadFile":"10000"
    },
    "debug":true 
}

如上所示,小程式的全域性配置是儲存在app.jason檔案中的。

從檔案內容可以看出小程式的全域性配置局並不多,包括頁面路徑(page)、視窗表現(window)、切換頁籤(tabBar)、網路超時設定(networkTimeout)、除錯模式(debug)。而且並不是每一項配置都是必需的。

在詳細介紹每一個配置項之前,先說一下小程式裡JSON配置的一些注意事項。

JSON檔案都是被包裹在一個大括號中 {},通過key-value的方式來表達資料。JSON的Key必須包裹在一個“雙引號”中,在實踐中,編寫 JSON 的時候,忘了給 Key 值加雙引號或者是把雙引號寫成單引號是常見錯誤。

JSON的值只能是以下幾種資料格式,其他任何格式都會觸發報錯,例如 JavaScript 中的 undefined。

  1. 數字,包含浮點數和整數
  2. 字串,需要包裹在雙引號中
  3. Bool值,true 或者 false
  4. 陣列,需要包裹在方括號中 []
  5. 物件,需要包裹在大括號中 {}
  6. Null

還需要注意的是 JSON 檔案中無法使用註釋,試圖新增註釋將會引發報錯。

下面我們詳細說明一下app.jason中每個配置項的型別及注意事件:

1.1 pages配置項

pages是程式必需的配置項。pages接受一個陣列(Array),用來指定小程式由哪些頁面組成。陣列的每一項都是字串型別,代表對應頁面的“路徑+檔名”。

pages配置時需要注意以下三點:

a)陣列第一項即小程式的啟動頁,即首頁;

b)小程式新增或減少頁面,都需要修改pages陣列;

c)檔名不需要加字尾,如"pages/index/index",小程式框架會自動尋找路徑下的四類檔案(.js/.jason/.wxml/.wxss)進行整合。

1.2 window配置項

window不是必需的配置項。沒有配置時系統將採用預設值。window接受物件值(Object),用來設定小程式的狀態列、導航欄、標題、視窗等物件的顏色、背景、內容屬性。

window的可配置的物件及其描述如下:

a)navigationBarBackgroundColor,設定導航欄背景顏色,value型別HexColor,預設值#000000;

b)navigationBarTextStyle,設定導航欄標題顏色,value型別String,僅支援black或white;

c)navigationBarTitleText,設定導航欄標題文字內容,value型別String;

d)backgroundColor,設定視窗的背景色,value型別HexColor,預設值#ffffff;

e)backgroundTextStyle,下拉背景字型、loading圖的樣式,value型別String,僅支援dark/light;

f)ebablePullDownRefresh,是否開啟下拉重新整理,value型別Boolean,預設值false。

示例:我們在app.jason中設定如下的window配置:

  "window": {
    "navigationBarBackgroundColor": "#405f80",
    "navigationBarTextStyle": "white",
    "navigationBarTitleText": "光與影",
    "backgroundColor":"#eeeeee",
    "backgroundTextStyle":"light"
  }

 則小程式產生的介面效果如圖:

1.3 tabBar配置項

 tabBar配置項可以實現小程式多頁籤切換的功能。tabBar用來指定標籤頁的樣式以及切換時對應的頁面。

tabBar配置項及其說明:

a)color,設定標籤上的文字預設顏色,value型別HexColor,必填項;

b)selectedColor,設定標籤上的文字選中時的顏色,value型別HexColor,必填項;

c)backgroundColor,標籤頁的背景色,value型別HexColor,必填項;

d)boderStyle,標籤的框線顏色,value型別String,預設值black,僅支援black或white,選填;

e)position,標籤欄的位置,value型別String,預設值bottom,可選值bottom或top,選填;

f)list,標籤頁列表,value型別Array,支援最少2個、最多5個標籤頁。

需要注意的是,list接受的是一個陣列值,陣列元素的順序就是標籤頁顯示的順序,陣列中的每一項也都是一個物件,其型別、功能描述如下(均是必填項):

a)pagePath,頁面路徑,需要在pages中預定義,value型別String;

b)text,標籤上按鈕文字,value型別String;

c)iconPath,標籤上icon圖示路徑,圖示大小不能超過40KB,value型別String;

d)selectedIconPath,標籤被選中時顯示的icon圖示路徑,圖示大小不能超過40KB,value型別String;

 下面的示例設定了2個標籤頁“閱讀”和“電影”,程式碼如下:

  "tabBar": {
    "color":"#dddddd",
    "selectedColor":"#3cc51f",
    "borderStyle": "white",
    "backgroundColor":"#ffffff",
    "list": [
      {
        "pagePath": "pages/posts/post",
        "text": "閱讀",
        "iconPath": "/images/tab/yuedu.png",
        "selectedIconPath": "/images/tab/yuedu_hl.png"
      },
      {
        "pagePath": "pages/movies/movies",
        "text": "電影",
        "iconPath": "/images/tab/dianying.png",
        "selectedIconPath": "/images/tab/dianying_hl.png"
      }
    ]
  }

介面的實際效果如下圖所示:

1.4 networkTimeout配置項

networkTimeout用於設定各種網路請求物件的超時時間,非必須配置項。可以設定網路請求超時的相關物件有request、connectSocket、uploadFile、downloadFile。時間單位均為毫秒。當然,這些超時若沒有設定, 則預設使用作業系統核心或遵循伺服器WebServer的設定值。

1.5 debug配置項

debug配置項用於是否開啟開發者工具的除錯模式。它的value型別是一個boolean值,預設是false。開啟後,頁面page的註冊、頁面路由、資料更新、事件觸發等除錯資訊將以info的形式,輸出在除錯功能的console皮膚上。開啟配置如下:

{
    "debug":true 
}

顯然開啟後除錯模式後,對開發者快速定位一些常見問題很有幫助,但在正式釋出時應當關閉此配置項開關。 

2、頁面配置 

小程式中的頁面配置page.jason,只能設定本頁面的視窗表現,也就是隻能設定window配置項的內容。頁面.jason檔案中的window配置值將覆蓋app.jason中的配置值。

因為頁面.jason檔案中只能設定window配置項,以決定本頁面的視窗表現,所以檔案中也無需寫window這個鍵值,直接寫window下的可配置項即可。window的可配置項已在本文(1.2)小節中說明。


 二、邏輯層

關於小程式邏輯層的概念和特點,在微信小程式開發框架(MINA)中已做闡述,此處不再贅述。

1、註冊程式的App()方法

 先來看一下App()方法的程式碼示例:

App({
    onLaunch:function(){
        //程式啟動時執行的初始化操作
    },
    onShow:function(){
        //程式進入前臺時執行的操作
    },
    onHide:function(){
        //程式進入後臺時執行的操作
    },
    onError:function(msg){
        console.log(msg)
    },
    globalData:'This is global data'
})

PS:前臺、後臺:使用者操作小程式的當前介面稱之為前臺,當點選關閉或按HOME鍵離開微信,小程式並沒有直接銷燬,而是進入後臺;當再次進入微信或再次開啟小程式,又會從後臺進入前臺了。

App()方法用來註冊一個程式,且只能註冊一次,存在於app.js中。它接受的引數是object型別:

a)onLaunch,生命週期函式,監聽小程式初始化,當小程式初始化完成時,會觸發onLaunch,且全域性只觸發一次;

b)onShow,生命週期函式,監聽小程式顯示,小程式啟動或從後臺進入前臺顯示,會觸發onShow;

c)onHide,生命週期函式,監聽小程式隱藏,小程式從前臺進入後臺會觸發onHide;

d)onError,錯誤監聽函式,小程式發生指令碼錯誤或API呼叫失敗,會觸發onError並帶出錯誤資訊;

e)開發者還可以新增任意object型別的引數,用this訪問;

可以使用全域性函式getApp()獲取小程式例項。使用示例如下:

//**.js
var app = getApp() 
console.log(app.globalData) 

//輸出'This is global data'

 

但是在App()函式中不要使用getApp(),使用this就可以拿到App()例項。

2、註冊頁面的page()方法

先來看一下page()方法的程式碼示例:

Page({
    data:{
        text:"This is page data."
    },

    onLoad:function(){
        //頁面載入時執行的初始化操作
    },
    onReady:function(){
        //頁面初次渲染時執行的操作
    },
    onShow:function(){
        //頁面顯示時執行的操作
    },
    onHide:function(){
        //頁面隱藏時執行的操作
    },
    onUnload:function(){
        //頁面解除安裝或關閉時執行的操作
    },
    onPullDownRefresh:function(){
        //頁面被使用者下拉時執行的操作
    },
    onReachBottom:function(){
        //頁面到達底部時執行的操作
    },
    onShareAppMessage:function(){
        //使用者分享時返回個性化的分享資料
    },

    //響應wxml繫結事件處理
    viewTap:function(){
    this.setData({
        text:'Set some data for update view'
    })
    }
})

page()方法用來註冊一個頁面。它接受object型別引數,用來指定頁面的初始資料、生命週期函式、事件處理函式等。每個頁面有且僅有一個page()方法,存在於該頁面的.js檔案中。

2.1 初始化資料

data引數提供頁面的初始化資料,作為頁面的第一次渲染。物件 data 將會以 JASON 的形式由邏輯層傳至檢視層,所以其資料必須是可以轉成 JASON 的格式:字串、數字、布林值、物件、陣列。

在檢視層通過WXML對資料進行繫結。示例程式碼如下:

<!--wxml-->
//渲染page()的資料
<view>{{text}}</view>

2.2 頁面生命週期函式

頁面的生命週期包括:onLoad、onShow、onReady、onHide、onUnload。

onLoad是頁面載入時執行的初始化操作。一個頁面只會呼叫一次,引數可以獲取wx.navigationTo和wx.redirectTo及<navigator />中的query。

onShow是頁面顯示時執行的操作。每次開啟頁面都會呼叫一次。

onReady是頁面渲染完成時執行的操作。一個頁面只會呼叫一次,代表頁面已經準備妥當,可以和檢視層進行互動。對頁面的設定(如wx.setNavigationBarTitle)應該在onReady之後。

onHide是頁面隱藏時執行的操作。當進行 navigateTo 或底部進行 tab 切換時呼叫。

onUnload是頁面解除安裝時執行的操作。當進行 redirectTo 或 navigateBack 操作時呼叫。

2.3 頁面相關事件處理函式

onPullDownRefresh是下拉重新整理時執行的操作,監聽使用者下拉重新整理事件。需要在頁面 .json 檔案的window配置項中開啟enablePullDownRefresh。當處理完資料重新整理後,wx.stopPullDownRefresh可以停止當前頁面的下拉重新整理。

onShareAppMessage是使用者分享時返回定製的分享內容。只有定義了此事件處理函式,右上角選單才會顯示“分享”按鈕。使用者點選分享按鈕的時候會呼叫。此事件需要return一個object物件,用於自定義分享內容。

title 是分享的標題,預設值是當前小程式的名稱。

path 是分享路徑,當前頁面的 path,必須是以 / 開頭的完整路徑。

onShareMessage示例程式碼如下:

page({
    onShareMessage:function(){
        return{
            title:'分享標題',
            path:'/page/url?id=5'
        }
    }
})

 2.4 檢視層繫結的事件處理函式 

page()方法除了初始化資料和生命週期函式,還可以定義一些特殊的事件處理函式。我們可以在檢視層通過對元件加入事件繫結,當滿足觸發事件時,就會執行page()中定義的事件處理函式。

示例程式碼如下:

<!--wxml 繫結tap事件到view元件上,函式名為viewTap-->
<view bindtap = "viewTap"> click me </view>

//page.js
page({
    //定義 viewTap 事件處理函式
    viewTap:function(){
        console.log('view tap')
    }
})

 2.5 頁面資料設定與展現 

在page()中我們使用setData函式來設定資料。改變對應的this.data的值。

this是指包含它的函式作為方法被呼叫時所屬的物件,在小程式中一般指呼叫頁面。

不能直接修改this.data,這樣無法改變頁面的狀態,還會造成資料不一致。

儘量避免一次設定過多的資料,單次不能超過1024KB。

setData函式引數是物件型別。以key、value的形式表示,將this.data中的key對應的值改變成value。其中key無須在this.data中預定義。

示例程式碼如下:

<!--index.wxml-->
<view>{{text}}</view>
<button bindtap = "changeText">Change normal data</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:{
        texe:'init data',
        array:[{text:'init data'}],
        object:{
            text:'init data'
        }
    },
    changeText:function(){
        //this.data.text = 'changed data'錯誤設定方法
        this.setData({
            text:'changed data'
        })
    },
    changeItemInArray:function(){
    //注意修改的key是資料路徑的形式(有引號)
        this.setData({
            'array[0].text':'changed data'
        })
    },
    changeItemInObject:function(){
    //注意修改的key是資料路徑的形式(有引號)
        this.setData({
            'object.text':'changed data'
        })
    },
    addNewField:function(){
    //注意新增的key是資料路徑的形式(有引號)
        this.setData({
            'newField.text':'new data'
        })
    }
})

 實際效果示例:

          

2.6 頁面棧及其例項獲取

框架以棧的形式維護了程式的所有頁面。當發生頁面切換的時候,頁面棧的表現如下:

路由方式   頁面棧表現
初始化 新頁面入棧。
開啟新頁面 新頁面入棧。
頁面重定向 當前頁面出棧,新頁面入棧。
頁面返回 頁面不斷出棧,直到目標返回,新頁面入棧。
Tab 切換 當前頁面出棧,新頁面入棧。

 

 

 

 

 

框架提供了獲取當前頁面棧例項的方法getCurrentPages(),頁面以陣列形式按棧的形式給出,第一個元素為首頁,最後一個元素為當前頁面。不要嘗試修改頁面棧,會導致路由及頁面狀態錯誤。

2.7 頁面路由

小程式框架管理所有頁面的路由。路由的觸發方式以及頁面的生命週期函式對應關係如下:

路由方式 觸發時機 路由後頁面 路由前頁面
初始化   小程式開啟的第一個頁面   onLoad,onShow  
開啟新頁面  

呼叫API wx.navigateTo 或

使用元件<navigator open-type="navigator"/>

onLoad,onShow   onHide  
頁面重定向

呼叫API wx.navigateTo 或

使用元件<navigator open-type="navigator"/>

onLoad,onShow onUnload
頁面返回

呼叫API wx.navigateTo 或

使用者按左上角返回按鈕

onShow onUnload
Tab 切換

呼叫API wx.switchTab 或使用元件<navigator open-type="switchTab"/>

或多 Tab 模式下使用者切換Tab

第一次開啟 onLoad,onShow;

否則 onShow

onHide

 

 

 

 

 

 

 

 

 

3、模組化與呼叫

3.1 檔案作用域

在頁面的JavaScript指令碼檔案(.js)中宣告的變數和函式只在該檔案中有效,不同的檔案中可以宣告相同名字的變數和函式,不會互相影響。

通過全域性函式getApp()可以獲取全域性的應用例項,如果需要全域性的資料可以在App()方法中設定,例如:

//app.js 
App({
    globalData:1
})

//a.js 
//在a.js中定義變數localValue 
var localValue = 'a' 
//在a.js中獲取App例項
var app = getApp() 
//修改a.js中獲取到的全域性資料值
app.globalData++ 

//b.js 
//在b.js中定義變數localValue,不影響a.js中的localValue 
var localValue = 'b' 
//假設a.js在b.js之前執行,那麼下面的語句之後globalData就會是2 
console.log(getApp().globalData)

 3.2 模組化

我們可以將一些公共的程式碼抽離成為一個單獨的.js指令碼檔案,作為一個模組。

模組只有通過 module.exports 才能對外暴露介面以供其他.js檔案引入使用。在需要使用公共模組的.js檔案中,使用 require(path)將公共程式碼引入。

示例程式碼如下:

//common.js 
function Hello(name) {
    console.log('Hello' + name + '!') 
}

module.exports = {
    sayHello: Hello
}

//下面的call.js使用common.js模組
//call.js 
var common = require('common.js') 
page({
    helloMINA:function(){
    common.sayHello('MINA')
    }
})

 4、微信原生API

小程式開發框架提供了功能豐富的微信原生API,可以方便我們調取微信提供的能力,如獲取使用者資訊、本地儲存、支付等。

微信原生的API共有八大類:介面API、檔案API、資料快取API、媒體API、網路API、位置API、裝置API以及微信開放介面。

微信API的共性特點:

wx.on開頭的API是監聽事件發生的API介面,接受一個回撥函式(CALLBACK)作為引數。當事件發生時會呼叫該回撥函式。

其他API介面都接受一個Object作為引數,除非有特殊約定。

Object中可以指定success、fail、complete方法來接收介面呼叫結果。success表示介面呼叫成功的回撥函式,fail是介面呼叫失敗的回撥函式,complete是介面呼叫結束的回撥函式且無論成功、失敗都會執行。

關於原生API的種類、名稱、作用的詳細說明可以參考微信小程式開發者文件中的API部分


 以上闡述的是小程式開發基礎中的「配置」與「邏輯層」部分,為避免篇幅過長,「檢視層」部分的講解將在單獨的文章中予以講述。

相關文章