簡(jiǎn)介:2018年9月份微信正式推出云開發(fā)平臺(tái),一石激起千層浪,什么是云開發(fā)?是不是以后就可以和后端研發(fā)說(shuō)拜拜了?是不是未來(lái)前端研發(fā)就可以一統(tǒng)微信小程序了?想想還有點(diǎn)小激動(dòng)了呢!
2018年9月份微信正式推出云開發(fā)平臺(tái),一石激起千層浪,什么是云開發(fā)?是不是以后就可以和后端研發(fā)說(shuō)拜拜了?是不是未來(lái)前端研發(fā)就可以一統(tǒng)微信小程序了?啥?我膨脹了嗎?我驕傲了嗎?我嘴角流口水了嗎?只是想想還有點(diǎn)小激動(dòng)了呢!

好了,好了,后端童鞋可以放下手里的刀了,這個(gè)微信小程序的云開發(fā)暫時(shí)還無(wú)法全面取代你們?cè)谖⑿哦说牡匚?,但是!不得不說(shuō)給前端開發(fā)帶來(lái)了很大的便利,值得前端童鞋們一探究竟。
云開發(fā)為開發(fā)者提供完整的云端支持,弱化后端和運(yùn)維概念,無(wú)需搭建服務(wù)器,使用平臺(tái)提供的 API 進(jìn)行核心業(yè)務(wù)開發(fā),即可實(shí)現(xiàn)快速上線和迭代,同時(shí)這一能力,同開發(fā)者已經(jīng)使用的云服務(wù)相互兼容,并不互斥。
也就是說(shuō),對(duì)于一些小程序,我們無(wú)需后端搭建服務(wù)器,提供數(shù)據(jù)庫(kù),整個(gè)項(xiàng)目完全可以由前端開發(fā)者來(lái)完成。這意味著前端開發(fā)者無(wú)需考慮如何構(gòu)建服務(wù)器之類的工作,即可完成整個(gè)微信小程序了。
好了,叨叨了這么多,想必你已經(jīng)迫不及待的要揭開它神秘的面紗了。
(1)俗話說(shuō)“巧婦難為無(wú)米之炊”,首先要做的就是下載微信提供的最新開發(fā)工具,網(wǎng)址為您奉上:
https://developers.weixin.qq.com/miniprogram/dev/devtools/download.html?t=18101520
(2)在啟動(dòng)界面,選擇”建立云開發(fā)快速啟動(dòng)模板”,就可以看到下面的開發(fā)平臺(tái)了:

其中,系統(tǒng)默認(rèn)會(huì)建立兩個(gè)文件夾,分別為:
– cloudfunctions 默認(rèn)存放云函數(shù)的文件夾
– miniprogram 默認(rèn)存放業(yè)務(wù)代碼的文件夾
如果你覺得,這是神馬名字,能不能起個(gè)高大上的名字。只有私人訂制版的名字,才能襯托我無(wú)與倫比的高貴氣質(zhì)~
比如說(shuō):李狗蛋和王鋼柱…

敲黑板,注意了,當(dāng)你修改名字后,一定要記得在 project.config.json 中對(duì)應(yīng)修改云函數(shù)和程序的路徑,否則小程序無(wú)法找到對(duì)應(yīng)的入口文件而報(bào)錯(cuò)。
細(xì)心的童鞋可能發(fā)現(xiàn),云函數(shù)的文件夾后面帶有一個(gè) cloud-demo 的小尾巴,這個(gè)是當(dāng)前云函數(shù)使用的云環(huán)境。云環(huán)境有啥用處呢?
由于云開發(fā)是實(shí)時(shí)上線更新的,假如你已經(jīng)上線了一版小程序,在本地開發(fā)的時(shí)候,實(shí)時(shí)修改該環(huán)境下的數(shù)據(jù)庫(kù)和云函數(shù)邏輯,那么使用同一環(huán)境的線上小程序也會(huì)變來(lái)變?nèi)?,再想想用戶一臉茫然的看著自已?dòng)來(lái)動(dòng)去的小程序界面,很調(diào)皮是不是?
好在,微信給每位開發(fā)者提供了兩套環(huán)境:
環(huán)境之大,
一次用不下,
一個(gè)上線,
一個(gè)開發(fā)!

每套環(huán)境的數(shù)據(jù)庫(kù)/云函數(shù)都是相互獨(dú)立的,只有在測(cè)試環(huán)境檢查的沒有問題了,再部署到線上。那么問題又來(lái)了,如何切換使用的云環(huán)境呢?
右擊云函數(shù)文件夾,如果之前切換過環(huán)境的話,會(huì)出現(xiàn)兩個(gè)候選環(huán)境,如果之前沒有切換過,則選擇更多設(shè)置,如下圖所示在新打開的界面中選擇當(dāng)前要使用的環(huán)境即可。

好了,環(huán)境準(zhǔn)備好后,讓我們開始愉快的(踩坑)開發(fā)之旅吧!
曾經(jīng)有位名人“沃·滋基碩德” 這樣教導(dǎo)我們:“你在奔向成功的路上總是會(huì)遇到困難,不要傷心,慢慢就習(xí)慣了!”

云開發(fā)包括三大主要內(nèi)容:云函數(shù),數(shù)據(jù)庫(kù),存儲(chǔ)管理,相當(dāng)于攔路虎一樣,橫跨在我們面前,在使用過程中需要注意哪些事項(xiàng)呢?讓我娓娓道來(lái):
何為云函數(shù)?
云函數(shù)是一段運(yùn)行在云端的代碼,無(wú)需管理服務(wù)器,在開發(fā)工具內(nèi)編寫、一鍵上傳部署即可運(yùn)行后端代碼。
我們可以在代碼區(qū)域的云函數(shù)文件夾,右擊新建 node.js 函數(shù),之后平臺(tái)會(huì)提示我們是否安裝依賴:

如需在云函數(shù)中操作數(shù)據(jù)庫(kù)、管理云文件、調(diào)用其他云函數(shù)等操作,可使用官方提供的 npm 包 wx-server-sdk 進(jìn)行操作。值得注意的是,一旦忘記安裝依賴,在 mac 系統(tǒng)下,則沒有挽回的入口,不是說(shuō)好了,浪子回頭金不換嗎?連個(gè)后悔機(jī)會(huì)也不給人家??!還好我們可以曲線救國(guó),在本地文件中,找到該云函數(shù)的文件夾,打開 CMD 終端執(zhí)行下面的命令:
npm install --save wx-server-sdk@latest
然后再上傳部署該云函數(shù),這樣就可以引入依賴了。
云函數(shù)的使用方式如下:
exports.main = (event, context) => {
let { userInfo, a, b} = event
let { openId, appId} = userInfo // 這里獲取到的 openId 和 appId 是可信的
let sum = a + b
return {
openId,
appId,
sum
}
}
其中 event 包含了小程序端調(diào)用該函數(shù)時(shí)傳過來(lái)的參數(shù),同時(shí)還包含了用戶登錄態(tài) openId 和小程序 appId 信息;
context 對(duì)象包含了此處調(diào)用的調(diào)用信息和運(yùn)行狀態(tài),可以用它來(lái)了解服務(wù)運(yùn)行的情況。
這里比較重要的是 openId ,客戶端的每個(gè)用戶都會(huì)有自己的 openId ,服務(wù)端可以根據(jù)這些 openId 來(lái)區(qū)分用戶。然而,當(dāng)我們滿心歡喜的想跑通上面獲取 openId 的示例時(shí),卻發(fā)現(xiàn)報(bào)錯(cuò)了:

看錯(cuò)誤提示是沒有獲取到 login 這個(gè)云函數(shù),但是打開云開發(fā)平臺(tái),該云函數(shù)明明存在的呀?而且這是官方給的的示例,怎么會(huì)出錯(cuò)呢?
這時(shí),停下來(lái)來(lái)思索一下,因?yàn)橛袃商组_發(fā)環(huán)境,是不是還需要定義小程序端調(diào)用的云環(huán)境呢?
想到這里茅塞頓開,于是在 app.js 文件下初始化云函數(shù)的時(shí)候,定義好要使用的云開發(fā)環(huán)境:
wx.cloud.init({
env: '使用云開發(fā)環(huán)境的ID',
traceUser: true
}
類似的,云函數(shù)在初始化時(shí),同樣需要對(duì)云開發(fā)環(huán)境進(jìn)行定義,
// 云函數(shù)入口文件
const cloud = require('wx-server-sdk')
cloud.init({
env: 'demo-id'
})
const db = cloud.database();
exports.main = async (event, context) => {
return db.collection('todos').get()
}
這樣,上面的云函數(shù)就是調(diào)用了 ‘demo-id’ 云環(huán)境下的 todos 集合的數(shù)據(jù)了。注意的是,該調(diào)用的環(huán)境可以和當(dāng)前開發(fā)環(huán)境不是同一套環(huán)境。
數(shù)據(jù)庫(kù)的界面如下圖所示:

改變數(shù)據(jù)庫(kù)有四種方法:
– 1.云開發(fā)平臺(tái)添加記錄;
– 2.云開發(fā)平臺(tái)導(dǎo)入數(shù)據(jù);
– 3.微信小程序端改變數(shù)據(jù)庫(kù);
– 4.云函數(shù)端改變數(shù)據(jù)庫(kù);
正所謂“尺有所短,寸有所長(zhǎng)。物有所不足,智有所不明”。這四種方法,各有優(yōu)點(diǎn):
(1)云開發(fā)平臺(tái)添加記錄,簡(jiǎn)單方便,不足之處在于,每條數(shù)據(jù)都要逐條輸入,不方便;
(2)云開發(fā)平臺(tái)導(dǎo)入數(shù)據(jù),可以同時(shí)導(dǎo)入大量的數(shù)據(jù),快速。注意的是,導(dǎo)入的json數(shù)據(jù)和常規(guī)的 json 格式不同,按照對(duì)象分割,并且對(duì)象之間不存在逗號(hào),如下所示:
{
"_id":"todo-identifiant-aleatoire",
"_openid":"user-open-id",
"description":"learn cloud database",
"done":false
}
{
"_id":"todo-identifiant-aleatoire-2",
"_openid":"user-open-id",
"description":"write a novel",
"done":false
}
(3)小程序端改變數(shù)據(jù)庫(kù),往往攜帶業(yè)務(wù)邏輯,但是受到各種權(quán)限的限制。小程序端新增的數(shù)據(jù),都會(huì)默認(rèn)帶有 _id(用以唯一標(biāo)志一條記錄) 和 openid(用以標(biāo)志記錄的創(chuàng)建者,即小程序的用戶)。這樣,根據(jù)數(shù)據(jù)庫(kù)中保存的 openid ,可以區(qū)分不同的用戶。反過來(lái),某位用戶也無(wú)法操作其他用戶的數(shù)據(jù),從而保證了數(shù)據(jù)的穩(wěn)定性。
(4)云函數(shù)端改變數(shù)據(jù)庫(kù),和小程序端類似的,云函數(shù)提供函數(shù)名稱 name,供小程序調(diào)用。下面就是小程序端調(diào)用云函數(shù)的方法:
wx.cloud.callFunction({
name: ‘云函數(shù)名字',
data: {
//傳入云函數(shù)的參數(shù)
},
success: res => {
//調(diào)用成功后的函數(shù)
},
fail: err => {
//調(diào)用失敗后的函數(shù)
}
})
可以看出,云函數(shù)也可以帶有業(yè)務(wù)邏輯,不同于小程序端對(duì)數(shù)據(jù)庫(kù)的操作,云函數(shù)是運(yùn)行在服務(wù)端的,具有至高無(wú)上的權(quán)利—— 棄 openid 如敝履,置權(quán)限于不顧,隨心所欲的對(duì)數(shù)據(jù)庫(kù)進(jìn)行增!刪!改!查!
綜上所述,我們可以使用在云開發(fā)平臺(tái)的導(dǎo)入功能,初始化 json 數(shù)據(jù),利用云開發(fā)平臺(tái)的添加修改功能,對(duì)數(shù)據(jù)進(jìn)行細(xì)節(jié)的調(diào)整,之后使用微信小程序端操作數(shù)據(jù)庫(kù),向數(shù)據(jù)庫(kù)中增加數(shù)據(jù),可以自動(dòng)引入 openid 來(lái)區(qū)分用戶數(shù)據(jù),最后如果想獲得更大的權(quán)利,就使用云函數(shù)對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作,再把調(diào)用的權(quán)限拋給小程序端。
云開發(fā)平臺(tái)上最后一位攔路虎是云存儲(chǔ)管理,它不吵不鬧,來(lái)者不拒的接收著要保存的數(shù)據(jù)。其界面如下圖所示

從上圖看出,通過“上傳文件”按鈕,可以在云開發(fā)控制臺(tái)上傳文件。此外,可以通過微信小程序的 uploadFile 函數(shù),上傳文件。謹(jǐn)記,一定要使用新建文件夾來(lái)規(guī)范劃分存儲(chǔ)的數(shù)據(jù),否則后期大量的存儲(chǔ)文件將是你揮之不去的噩夢(mèng)。
圖中 fileId 即是文件的存儲(chǔ)地址,無(wú)論是從云開發(fā)平臺(tái)還是從客戶端上傳的文件,系統(tǒng)都會(huì)自動(dòng)分配給每個(gè)文件對(duì)應(yīng)的 fileId。當(dāng)然也可以通過微信小程序的 uploadFile 函數(shù),上傳文件。下面的云函數(shù)代碼就使用了存儲(chǔ)管理中保存的文件,返回給小程序端調(diào)用:
// 云函數(shù)入口文件
const cloud = require('wx-server-sdk')
cloud.init()
// 云函數(shù)入口函數(shù)
exports.main = async (event, context) => {
const fileList = [
'cloud://cloud-demo-c5b56e.636c-cloud-demo-c5b56e/swiperImg/img_1.jpg',
'cloud://cloud-demo-c5b56e.636c-cloud-demo-c5b56e/swiperImg/img_2.jpg',
'cloud://cloud-demo-c5b56e.636c-cloud-demo-c5b56e/swiperImg/img_3.jpg'
]
const result = await cloud.getTempFileURL({
fileList: fileList,
})
return result.fileList
}
上面解釋了文件在云端保存的地址,那么在小程序端把文件上傳到云存儲(chǔ)中的地址又是什么呢?
假如在小程序端,實(shí)現(xiàn)本地的圖片上傳到云服務(wù)器的功能,首先要獲取本地文件的臨時(shí)路徑:
wx.chooseImage({
//選擇手機(jī)圖片
chooseEvt(){
let that = this;
wx.chooseImage({
count: 1,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success(res) {
// tempFilePath可以作為img標(biāo)簽的src屬性顯示圖片
const tempFilePaths = res.tempFilePaths[0];
that.setData({
chooseImg: tempFilePaths
})
that.uploadImg(tempFilePaths);
}
})
}
下面是上傳到服務(wù)器的代碼:
uploadImg(tempFilePaths){
let str = tempFilePaths;
let name = str.split('.').reverse()[1] +'.'+str.split('.').reverse()[0];
let names = name.split('//')[1];
let that = this;
wx.cloud.uploadFile({
cloudPath: 'swiperImg/'+names,
filePath: str, // 小程序臨時(shí)文件路徑
success: res => {
that.setData({
imageId: res.fileID
})
},
fail: err => {
console.log(err)
}
})
}
其中 wx.cloud.uploadFile 帶有的參數(shù) cloudPath 就是上傳到服務(wù)器的存儲(chǔ)地址。既然上面示例中已經(jīng)給出了結(jié)果,我也就不賣關(guān)子了,cloudPath 使用的是相對(duì)地址,而不是存儲(chǔ)地址 “cloud://cloud-demo-c5b56e.636c-cloud-demo-c5b56e/swiperImg/”。另外上傳文件的名字為了避免自己定義,使用了上傳文件本身的名字。但是!要注意的是, 手機(jī)端和電腦端上傳文件的路徑是不一樣的, 我們來(lái)看一下,在電腦端上傳圖片,得到的文件臨時(shí)地址 tempFilePaths 是
"http://tmp/wx81c95cafc368ba2d.o6zAJsxvC5wiHIIVQOpRPFVOADDM.NLBDb9oLxX1D1f412643685c68c106d42e1757f77691.png"
而手機(jī)端得到的 tempFilePaths 則是:
"wxfile://tmp_wx81c95cafc368ba2do6zAJsxvC5wiHIIVQOpRPFVOADDMNLBDb9oLxX1D1f412643685c68c106d42e1757f77691.png"
可以看出,除了文件頭不一樣外,手機(jī)端得到的地址并沒有中間的 “·”,假如像上面的代碼一樣,按照 “·” 進(jìn)行分割地址,則手機(jī)端得到的 name 就會(huì)帶有 wxfile:// ,這樣保存到云端存儲(chǔ)的時(shí)候就會(huì)一直提示 cloudPath 路徑不對(duì),但是在電腦端調(diào)試的時(shí)候,由于返回的圖片臨時(shí)路徑帶有多個(gè) “·”, 就不會(huì)出現(xiàn)這問題,話說(shuō),第一次遇到這個(gè)問題的時(shí)候,一度懷疑是不是云函數(shù)還需要走什么上線流程,才能在手機(jī)端看到效果呢。
微信云開發(fā)功能,給前端帶來(lái)獨(dú)立開發(fā)微信小程序的能力。一經(jīng)發(fā)布,便引起廣大開發(fā)者的關(guān)注。由于推出的不久,在開發(fā)過程中還有些問題無(wú)法找到類似的解答,只能不斷的翻閱官方文檔和調(diào)試。當(dāng)然還有官方提供的論壇[1],只是如果著急想要得到解答,還是要靠自己。
好了,說(shuō)了這么多,其實(shí)官方文檔中的 API,大多都沒有介紹。文末給出了官方文檔的鏈接[2],里面說(shuō)的很是詳細(xì)了。 本文旨在使用云開發(fā)過程中,總結(jié)分享遇到的哪些問題,拋磚引玉,期待各位走過路過的童鞋留言,說(shuō)一說(shuō)你在使用微信小程序中的心得。