1. 程式人生 > >微信小程式開發系列——5.前端頁面開發

微信小程式開發系列——5.前端頁面開發

摘要:本文說明了微信前端頁面開發的基本架構,說明了組成檔案各自的詳細結構,通過這幾個檔案的協同工作,微信小程式開發框架可以實現頁面Page中檢視層和邏輯層的統一。

0. 簡介

根據之前開發者工具和開發框架簡介的內容,我們把官方demo和開發者工具安裝好以後,就可以開始準備微信小程式的web開發了。

這裡寫圖片描述

在開發的主要介面,點選開發者工具左側導航的“編輯”,我們可以看到這個專案,已經初始化幷包含了一些簡單的程式碼檔案。最關鍵也是必不可少的,是 app.js、app.json、app.wxss 這三個。

1. App系列配置檔案

在 app.js、app.json、app.wxss 這三個檔案中,.js字尾的是指令碼檔案,.json字尾的檔案是配置檔案,.wxss字尾的是樣式表文件。微信小程式會讀取這些檔案,並生成小程式例項。

下面我們簡單瞭解這三個檔案的功能,方便修改以及從頭開發自己的微信小程式。

1.1 App.js

app.js是小程式的指令碼程式碼。我們可以在這個檔案中監聽並處理小程式的生命週期函式、宣告全域性變數。呼叫框架提供的豐富的 API,如本例的同步儲存及同步讀取本地資料。


App({
  onLaunch: function () {
    // 呼叫 API 從本地快取中獲取資料
    var logs = wx.getStorageSync('logs') || []
    logs.unshift(Date.now())
    wx.setStorageSync('logs'
, logs) }, getUserInfo:function(cb){ var that = this; if(this.globalData.userInfo){ typeof cb == "function" && cb(this.globalData.userInfo) }else{ // 呼叫登入介面 wx.login({ success: function () { wx.getUserInfo({ success: function (res)
{
that.globalData.userInfo = res.userInfo; typeof cb == "function" && cb(that.globalData.userInfo) } }) } }); } }, globalData:{ userInfo:null } })

1.2 App.json

app.json 是對整個小程式的全域性配置。我們可以在這個檔案中配置小程式是由哪些頁面組成,配置小程式的視窗背景色,配置導航條樣式,配置預設標題。注意該檔案不可新增任何註釋。當有新建的頁面時,需要在app.json的”pages”中新增相對路徑。

{
  "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
}

1.3 App.wxss

3、app.wxss 是整個小程式的公共樣式表。我們可以在頁面元件的 class 屬性上直接使用 app.wxss 中宣告的樣式規則,和css的寫法是一樣的。

.container {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: space-between;
  padding: 200rpx 0;
  box-sizing: border-box;
}

我們注意到,在例項程式的程式碼中還有2個資料夾,一個是pages,一個是utils。

utils是放通用工具類方法的一個資料夾,是傳統 Javascript 中 “function” 式的開發方法,在需要使用某些方法時,在當前js文件中使用require引用裡面的 js 檔案,然後直接呼叫該方法即可。

pages資料夾存放所有頁面檔案,每一個資料夾代表一個頁面,我們著重講一下這個pages。

2. pages詳解

用圖片來展示的話,每個page內部各自的邏輯關係是這樣的:

這裡寫圖片描述

小程式的Page由WXML(index.wxml) 與 WXSS(index.wxss) 兩大部分組成,由檢視最小單元 - 元件來進行展示。檢視層將邏輯層的資料、配置檔案(index.js+index.json)反應成檢視,同時將檢視層中定義的事件傳送給邏輯層。

在WXML中,使用預先定義好的樣式渲染介面(藍色的圓角矩形),並使用動態繫結的方法從邏輯層獲取部分資料(紅色的正方形),並編寫觸發事件函式(黃色的六邊形)作為監聽器,讓使用者的操作能得到相應的反饋,以此達到邏輯層和檢視層的統一。

2.1 wxml

<!--index.wxml-->
<view class="container">
  <view  bindtap="bindViewTap" class="userinfo">
    <image class="userinfo-avatar" src="{{userInfo.avatarUrl}}" background-size="cover"></image>
    <text class="userinfo-nickname">{{userInfo.nickName}}</text>
  </view>
  <view class="usermotto">
    <text class="user-motto">{{motto}}</text>
  </view>
</view>

本例中使用了<view/><image/><text/>來搭建頁面結構,繫結資料和互動處理函式,其中基本可以看做是:<view>代替了前端開發中的<div>。其餘的程式碼風格和html的編寫非常相似。該例子中,其中一個<text>元件裡綁定了後臺動態變化的變數userInfo.nickNamemotto,我們把這個叫做資料繫結。

資料繫結在小程式中是最簡單的使用資料方式,用雙大括號將變數包起來,如果元件有屬性則需將資料放置於引號之外。在這個text中,當前變數是寫在兩個<text>標誌之間的。

<text class="userinfo-nickname">{{userInfo.nickName}}</text>

2、bindtap函式
在當前例子中我們可以發現一個屬性叫做 bindtap 的東西,仔細看第二行:

  <view  bindtap="bindViewTap" class="userinfo">  

這個東西就是剛才在圖1中的展示的六邊形代表的意思——事件觸發函式。啥?你問我什麼是“事件”?如果用前端的說法,就是繫結在檢視上的一個元件,使用者操作這個元件就可以將前臺的行為返回到邏輯層(js檔案)進行處理。

以這份程式碼為例,當你點選這個<view>元件時,在index.js中,就有一個bindViewTap()函式就已經觸發並執行相應的功能。當這個view元件被按下時,框架會觸發一個event事件,並將該事件通過引數傳到bindViewTap(event)函式中執行。可以在index.js中列印一下這個event含有的引數:

//index.js
Page({ 
 bindViewTap: function(event) { 
 console.log(event) 
 } 
}) 

點選這個view元件,可以看到打印出來的log如下:

{ 
"type": "tap", 
"timeStamp": 1252, 
"target": { 
 "id": "tapTest", 
 "offsetLeft": 0, 
 "offsetTop": 0, 
 "dataset": { 
 "hi": "MINA"
 } 
}, 
"currentTarget": { 
 "id": "tapTest", 
 "offsetLeft": 0, 
 "offsetTop": 0, 
 "dataset": { 
 "hi": "MINA"
 } 
}, 
"touches": [{ 
 "pageX": 30, 
 "pageY": 12, 
 "clientX": 30, 
 "clientY": 12, 
 "screenX": 112, 
 "screenY": 151 
}], 
"detail": { 
 "x": 30, 
 "y": 12 
} 
} 

當邏輯層函式需要獲取相關檢視的資訊時, 可以從引數event中獲取。
例如,構造一個<input>元件:

//index.wxml
<input bindinput="inputchar"/>

然後再在index.js檔案中編寫inputchar(event)函式:

//index.js
inputchar: function(event){
    var str = e.detail.value;//獲取當前控制元件的value,在input元件中就是輸入的字串
    console.log(str);
}

我們在input欄中輸入字元時,就可以監聽到輸入值的變化情況,每輸入一個字元時,inputchar函式都被觸發了一遍,並在控制檯打印出輸入的字串。

這裡寫圖片描述

2.2 index.js

​ index.js 是頁面的指令碼檔案,在這個檔案中我們可以監聽並處理頁面的生命週期函式、獲取小程式例項,宣告並處理資料,響應頁面互動事件等。

//index.js
//獲取應用例項
var app = getApp()
Page({
  data: {
    motto: 'Hello World',
    userInfo: {}
  },
  //事件處理函式
  bindViewTap: function() {
    wx.navigateTo({
      url: '../logs/logs'
    })
  },
  onLoad: function () {
    console.log('onLoad')
    var that = this
    //呼叫應用例項的方法獲取全域性資料
    app.getUserInfo(function(userInfo){
      //更新資料
      that.setData({
        userInfo:userInfo
      })
    })
  }
})

每個頁面都需要註冊,index.js用Page()這個函式來註冊一個頁面,它接受一個object引數,用這個引數來指定頁面的初始資料,生命週期函式,事件處理函式。

屬性 型別 描述
data Object 頁面的初始資料
onLoad Function 生命週期函式--監聽頁面載入
onReady Function 生命週期函式--監聽頁面初次渲染完成
onShow Function 生命週期函式--監聽頁面顯示
onHide Function 生命週期函式--監聽頁面隱藏
onUnload Function 生命週期函式--監聽頁面解除安裝
onPullDownRefreash Function 頁面相關事件處理函式--監聽使用者下拉動作
其他 Any 開發者可以新增任意的函式或資料到 object 引數中,用 this 可以訪問

2.3 wxss

index.wxss 是頁面的樣式表:

/**index.wxss**/
.userinfo {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.userinfo-avatar {
  width: 128rpx;
  height: 128rpx;
  margin: 20rpx;
  border-radius: 50%;
}

.userinfo-nickname {
  color: #aaa;
}

.usermotto {
  margin-top: 200px;
}

頁面的樣式表是非必要的。當有頁面樣式表時,頁面的樣式表中的樣式規則會層疊覆蓋 app.wxss 中的樣式規則。如果不指定頁面的樣式表,也可以在頁面的結構檔案中直接使用 app.wxss 中指定的樣式規則。其中樣式表絕大多數的寫法與css是一模一樣的。

2.4 index.json

index.json是頁面的配置檔案,這個配置檔案是非必要的。當有頁面的配置檔案時,配置項在該頁面會覆蓋 app.json 的 window 中相同的配置項。如果沒有指定的頁面配置檔案,則在該頁面直接使用 app.json 中的預設配置。

3. 頁面展示

執行結果如下:

這裡寫圖片描述

這裡寫圖片描述

手機預覽(只有獲得AppId的才有許可權預覽)

這裡寫圖片描述

以上是微信小程式前端開發的基本流程,而實際上要做一個內容可以更新的小程式,單有前端開發是遠遠不夠的,還需要後臺開發。後臺開發與web開發的後臺基本無異,可以選擇用java、php、nodejs等任一語言,有一點需要注意的是小程式後臺伺服器必須是https協議的,這就要求必須購買雲伺服器,申請SSL證書,並將後臺伺服器設定成https服務。而做這些的前提是要先購買好伺服器、資料庫和域名。以上的資源配置統統可以到騰訊雲主頁去購買。關於後臺伺服器的配置,可以參考開發者工具以及開發框架簡介

如果在開發時還有困難,還可以參考W3Cschool的文件內容,我在開發現在的這個軟體時,基本都是參考這裡的文件的,雖然是照搬官網的內容,但是整理得非常詳細,邏輯清晰實用。