1. 程式人生 > >小程式雲開發實戰

小程式雲開發實戰

由於小程式本身儲存資料的能力有限,所以不可能將大量的資料儲存在客戶端,而且將資料儲存在本地既不安全,也無法與其他小程式使用者共享,所以大多數小程式都需要一個服務端,服務端可以用多種技術實現,如 PHP、Node.js、Python、Asp.net、Java EE 等。不管使用哪種技術實現服務端,開發一款小程式都需要至少配備兩個程式設計師,一個是開發小程式的程式設計師,一個是開發服務端的程式設計師;而且這兩個程式設計師之間還需要不斷溝通,以便確認共同遵循的介面。

開發一款小程式需要兩名或更多的程式設計師參與,一直困擾著很多小的創業公司,因為多僱傭一個人,就會增加很多成本。所以基於這個痛點,很多公司推出了雲開發技術,例如 Bmob 就是較早推出雲開發的公司,所謂雲開發,就是將服務端的功能都封裝起來,然後向客戶端提供 API 訪問這些封裝的功能。服務端的主要功能無外乎資料儲存、檔案上傳下載、視訊/音訊流等功能。這些功能大多開發都不困難,但比較費時,所以將其封裝起來供客戶端呼叫是一個非常好的主意。

騰訊最近推出了自己的雲開發系統,不過這個雲開發系統目前只能用於小程式,而且只提供瞭如下三種:

  • 雲資料庫
  • 雲端儲存
  • 雲函式

雲資料庫是指在服務端提供的資料庫服務,小程式雲提供的資料庫屬於文件資料庫,文件資料庫有別於關係型資料庫。傳統的關係型資料庫中可以儲存若干個表,每一個表由若干條記錄組成。但文件資料庫儲存的是 JSON 格式的資料,每一個 JSON 文件相當於關係型資料庫中的一個表。也就是說,文件資料庫儲存的是 JSON 文件的集合。非常流行的 MongoDB 就是典型的文件資料庫。雲資料庫個組成部分對應的關係如下表所示。

關係資料庫文件資料庫
資料庫(DataBase) 資料庫(DataBase)
表(table) 集合(collection)
行(row) 記錄(record/doc)
列(column) 欄位(field)

雲端儲存為小程式提供了遠端上傳和下載檔案的能力。下載可以提供許可權管理,小程式可以通過相應的 API 實現檔案的上傳和下載功能。

雲函式就是一段可以執行在服務端的程式碼,之所以要將部分程式碼在服務端執行,主要有如下兩個原因:

  • 部署多個使用者共享,且容易維護的程式碼
  • 獲取敏感資訊,如 AppID、OpenID 等

搭建雲開發環境

現在讓我們來開發第一個與雲的小程式,首先應該下載最新版的微信開發者工具,然後在小程式後臺獲取 AppID。使用雲開發功能,必須使用真實的 AppID,不能使用測試用的 AppID。

啟動微信開發者工具,新建立一個小程式工程。在建立小程式工程的過程中,需要輸入 AppID 和專案名稱,然後在最下面的目標列表中選擇“建立雲開發快速啟動模板”選項,如下圖所示。

image.png

建立完支援雲開發的小程式工程後,工程目錄結構和 IDE 主介面如下圖所示。當前工程預設帶了一些例子(模板中的例子)來幫助理解和開發基於雲的小程式。

image.png

如果第一次使用這個 AppID 開發基於雲的小程式,應該單擊介面上方的“雲開發”按鈕,會顯示如下圖所示的頁面。

image.png

這是一個開通雲服務的頁面,單擊“開通”按鈕,就會開通用於雲開發的服務。在開通的過程中會出現如下圖所示的確認對話方塊,單擊”確定“按鈕進入下一個設定頁面。

image.png

這個頁面是”新建環境“頁面,如下圖所示。需要輸入“環境名稱”,一個任意的字串。在下面列出了基礎版的配置,如資料庫儲存空空間、雲函式數量等。如果想要更多的資源,那以後肯定是要收費的,天下沒有免費的午餐。不過這個配置做實驗和使用者量不是非常大的小程式還是夠用的。

image.png

單擊“確定”按鈕,建立一個環境,然後進入如下圖所示的雲開發控制檯。在這個控制檯中可以管理使用者、雲資料庫、雲端儲存、雲函式及統計分析,並且會顯示相關的資訊,如今日 API 呼叫:

image.png

如果想建立新環境,可以將滑鼠放在右側當前環境 minicloud 上,會彈出如下圖所示的選單,單擊”建立新環境“選單項則會建立一個新的環境,目前每個小程式賬號課免費建立兩個新環境。

image.png

部署 login 雲函式

模板會預設建立一個 login 雲函式,用於返回 OpenID(標識當前微信登入使用者的 ID),所以在開發基於雲的小程式之前,首先要先部署 login 雲函式。

選中 login 雲函式,在右鍵選單中單擊“上傳並部署”選單項進行部署,如下圖所示。

image.png

成功部署 login 雲函式後,回到小程式的主頁面,單擊“點選獲取 openid”按鈕,如圖所示,則會通過 login 雲函式獲取 openid。

image.png

現在我們來開發第一個基於雲的小程式,這個小程式非常簡單,就是在一個集合中插入一條資料,也就是一個 JSON 格式的文字。

一個集合就相當於一個表。選擇環境後,小程式就會預設有一個數據庫,所以就不需要單獨建立資料庫了,只需要在該資料庫中建立若干個集合(表)即可。

首先開啟雲開發控制檯,切換到“資料庫”頁面,單後單擊左上角的“新增集合”,彈出如下圖所示的“新增集合”對話方塊,輸入集合的名字,然後單擊“確定”按鈕新增集合。

image.png

建立一個新集合後的效果如下圖所示。可以通過單擊右側的“新增記錄”匯入 json 或 csv 檔案,每個檔案最大 50 MB。不過本課並不會通過雲開發控制檯匯入,而是使用程式碼來插入文件。

image.png

獲得 openid 後,會跳到 userConsole 頁面,因此我們在這個頁面的 onLoad() 函式中向 test 集合插入一個 json 文件。

在小程式開發工具中定位到 userConsole.js 檔案,並找到 onLoad() 函式,如下圖所示。

image.png

在 onLoad() 函式中會從全域性變數(globalData)中獲取 openid。操作集合首先要通過 init() 函式初始化環境,init() 函式的語法格式如下:

wx.cloud.init({env:envname})

其中,envname 是字串型別的值,表示要使用的環境名,因為在前面已經建立了一個名為 minicloud 的環境了,所以本例的 envname 的值是'minicloud'。

使用下面的程式碼獲取資料庫和集合物件:

    const db = wx.cloud.database()
    const test = db.collection('test')

其中,test 是前面建立的集合名。

最後使用 add() 方法插入 json 格式的資料,完整的程式碼如下:

    wx.cloud.init({env:'minicloud'})
    const db = wx.cloud.database()
    const test = db.collection('test')

    test.add({
      // data 欄位表示需新增的 JSON 資料
      data: {

        name: "Bill",
        age:30       
      },
      success: function (res) {       
        //  輸出成功插入後的id以及其他資訊
        console.log(res)
      }
    })

現在重新執行程式,獲取 openid 後,就會在小程式開發者工具的 Console 中看到如下圖的資訊。

image.png

回到雲開發控制檯,會看到 test 集合多瞭如下圖所示的資料,這表明 json 文件已經插入成功。

image.png

現在來完善前面編寫的基於雲的小程式,這個小程式儘管可以向雲資料庫中插入資料,不過程式碼與模板程式碼混在了一起,在真正的小程式專案中,不可能讓使用者先單擊按鈕獲得 openid,再進行下面的操作,因此現在需要重新編寫基於雲的小程式,主要包括如下功能。

  • 從文字輸入元件中輸入姓名和年齡,單擊“插入資料”按鈕向雲資料庫插入包含姓名和年齡的資料。
  • 從文字輸入元件中輸入記錄 ID,單擊“查詢資料”按鈕,從雲資料庫中查詢相關的資料,並將查詢到的資料中的姓名和年齡顯示在頁面上。

小程式的主介面如下圖所示。

image.png

為了在我們自己頁面上實現這些功能,首先在小程式工程中建立一個 main 目錄,並建立如下圖所示的檔案。

image.png

接下來修改 app.json 檔案,將 main 頁面變成首頁(第一個顯示的頁面),也就是將“pages/main/main”放在 pages 陣列的第一個元素的位置,修改後的 app.json 檔案的內容如下:

{
  "cloud": true,
  "pages": [
    "pages/main/main",
    "pages/userConsole/userConsole",
    "pages/storageConsole/storageConsole",
    "pages/databaseGuide/databaseGuide",
    "pages/addFunction/addFunction",
    "pages/deployFunctions/deployFunctions",
    "pages/chooseLib/chooseLib"
  ],
  "window": {
    "backgroundColor": "#F6F6F6",
    "backgroundTextStyle": "light",
    "navigationBarBackgroundColor": "#F6F6F6",
    "navigationBarTitleText": "雲開發 QuickStart",
    "navigationBarTextStyle": "black"
  }
}

現在重新執行小程式,會看到 main 頁面已經成為了小程式的首頁。由於本例的頁面需要用到一些元件,因而需要先在 main.wxml 檔案中輸入下面的程式碼完成 main 頁面的佈局。

<view>
  <input style='margin-top: 40rpx;' placeholder="請輸入姓名" value="{{name}}" bindinput="bindKeyInputName" />
  <input style='margin-top: 40rpx;' placeholder="請輸入年齡" value="{{age}}" bindinput="bindKeyInputAge" />
  <button style='margin-top: 40rpx;' bindtap='insertData'>插入資料</button>
  <input style='margin-top: 40rpx;' placeholder="請輸入記錄ID" value="{{recordId}}" bindinput="bindKeyInputId" />

  <button style='margin-top: 40rpx;' bindtap='queryData'>查詢資料</button>

  <text style='margin-top: 40rpx;'>
     姓名:{{nameResult}}
  </text>
  <text style='margin-top: 80rpx;'>
     年齡:{{ageResult}}
  </text>
</view>

在 main.wxml 檔案中,包含 3 個 <input>元件和 2 個 text 元件,這 5 個元件分別與 age、name、recordId,nameResult 和 ageResult 五個變數繫結,修改和獲取這 5 個元件的值也只需要考慮這 5 個變數即可。

在小程式中呼叫雲 API 之前,必須要獲取小程式的 openid,這個 openid 表示當前小程式的使用者 ID。由於進入小程式必須要通過微信,因而小程式使用與微信相同的使用者驗證體系,因此,小程式就不需要單獨登入了,而 openid 就是小程式是否登入的憑證。

獲取 openid 的程式碼已經包含在模板中了,只需要找到 index.js 檔案,並搜尋 onGetOpenid() 函式,會看到如下的程式碼。

  onGetOpenid: function() {
    // 呼叫雲函式
    wx.cloud.callFunction({
      name: 'login',
      data: {},
      success: res => {
        console.log('[雲函式] [login] user openid: ', res.result.openid)
        app.globalData.openid = res.result.openid
        wx.navigateTo({
          url: '../userConsole/userConsole',
        })
      },
      fail: err => {
        console.error('[雲函式] [login] 呼叫失敗', err)
        wx.navigateTo({
          url: '../deployFunctions/deployFunctions',
        })
      }
    })
  }

上面的程式碼用於呼叫名為 login 的雲函式獲取小程式的 openid。通常只需要將 onGetOpenid() 函式中的程式碼直接複製到 main.js 檔案中的 onLoad() 函式即可。

向雲資料庫插入資料的程式碼前面已經學過,一會兒大家可以看本例完整的程式碼。從雲資料庫中查詢資料可以使用下面的程式碼。

db.collection(集合名).doc(記錄ID).get(
    {
        //  查詢到資料後觸發,res引數值包含的查詢到 資料
        success:function(res) {
        },
       //  未查詢到資料觸發
       fail:function(res) {
      }
})

main.js 中完整的實現程式碼如下:

// miniprogram/pages/main/main.js
const app = getApp()
Page({

  /**
   * 頁面的初始資料
   */
  db:undefined,
  test:undefined,
  data: {
    name:'',
    age:'',
    recordId:'',
    nameResult:'',
    ageResult:''    
  },

  /**
   * 生命週期函式--監聽頁面載入
   */
  onLoad: function (options) {
    var that = this
    //  呼叫login雲函式獲取openid
    wx.cloud.callFunction({
      name: 'login',
      data: {},
      success: res => {
        console.log('[雲函式] [login] user openid: ', res.result.openid)
        app.globalData.openid = res.result.openid
        wx.cloud.init({ env: 'minicloud' })
        that.db = wx.cloud.database()
        that.test = that.db.collection('test')
      },
      fail: err => {
        console.error('[雲函式] [login] 呼叫失敗', err)
        wx.navigateTo({
          url: '../deployFunctions/deployFunctions',
        })
      }
    })

  },
  // 單擊“插入資料”按鈕呼叫該函式
  insertData:function() {
    var that = this
    try
    {
     //  將年齡轉換為整數型別值
      var age = parseInt(that.data.age)
     //  如果輸入的年齡不是數字,會顯示錯誤對話方塊,並退出該函式
      if(isNaN(age))
      {
        //  顯示錯誤對話方塊
        wx.showModal({
          title: '錯誤',
          content: '請輸入正確的年齡',
          showCancel: false
        })
        return
      }  
      //  向test資料集新增記錄
      this.test.add({
        // data 欄位表示需新增的 JSON 資料
        data: {
          name: that.data.name,
          age:  age
        },
        //  資料插入成功,呼叫該函式
        success: function (res) {
          console.log(res)
          wx.showModal({
            title: '成功',
            content: '成功插入記錄',
            showCancel:false
          })
          that.setData({
            name:'',
            age:''
          })
        }
      })
    }
    catch(e)
    {
      wx.showModal({
        title: '錯誤',
        content: e.message,
        showCancel: false
      })

    }
  },
 //  單擊“查詢資料”按鈕執行該函式
  queryData:function() {
    var that = this
     //  根據記錄ID搜尋資料集  
    this.db.collection('test').doc(this.data.recordId).get({
      // 找到記錄集呼叫
      success: function (res) {  
         //  將查詢結果顯示在頁面上  
        that.setData({
          nameResult:res.data.name,
          ageResult:res.data.age
        })

      },
     //  未查到資料時呼叫
      fail:function(res) {
        wx.showModal({
          title: '錯誤',
          content: '沒有找到記錄',
          showCancel: false
        })
      }
    })

  },
 //  下面的函式用於當更新input元件中的值時同時更新對應變數的值
  bindKeyInputName: function (e) {
    this.setData({
      name: e.detail.value
    })
  },
  bindKeyInputAge:function(e) {
    this.setData({
      age: e.detail.value
    })
  },
  bindKeyInputId:function(e) {
    this.setData({
      recordId:e.detail.value
    })
  },

})

現在重新執行小程式,並新增一些資料,看到雲開發控制檯中的 test 集合下多了幾條記錄,如下圖所示,這表明已經將資料成功插入 test 集合。

image.png

現在回到小程式開發介面,在“查詢按鈕”上方的文字輸入框中輸入一條記錄的 ID,單擊“查詢資料”按鈕,會看到按鈕下方會顯示如下圖的查詢結果,如果未查詢到結果,會顯示一個提示對話方塊。

image.png

成功通過 login 雲函式獲取 openid 後,會顯示如下圖的頁面。現在就可以使用雲 API 來開發小程式了。

image.png