- 蘇格團隊
- 做者:Brady
最近團隊內部須要用到一個小程序,主要功能簡單歸納是團隊成員之間能夠相互發送評價,並可以查看本身收到和發出的評價以及團隊中各成員收到的評價數量。 開發人員一開始是隻有我一我的,以前並無過開發小程序的經驗。因而就毅然開始了小程序開發的踩坑之路。css
技術選型包括前端框架以及服務端語言及數據庫的選型。
前端技術選型:
在前端方面,但願可以達到的目標是:前端
目前流行的小程序框架主要有三款,分別是WePy、mpvue、Taro。
根據上述的目標來篩選的話,基本上這三款都是符合要求的。前兩款的代碼風格都是相似於vue,第三款是相似react的語法,而且能夠將一份代碼轉換爲h五、RN、支付寶小程序等。因爲本人所在公司用的技術棧主要爲react,爲了減小學習成本和後期換人開發維護的成本,最終選擇taro做爲前端的框架。
服務端技術選型:
在服務端方面,因爲我只會用nodejs和mongodb,因此選擇很少。打開小程序的開發者瞭解到有提供雲開發的功能,那就在這兩種方案之中挑一個了。
若是使用nodejs+mongodb本身搭建服務端的話,須要本身去搭建服務器和運維,可是使用雲開發的話,騰訊雲能夠免費提供兩臺服務器,而且小程序有提供api能夠在頁面操做數據庫的數據,開發起來應該效率會很高。
考慮到須要開發的小程序並不複雜並且用戶量只是部門內的幾十我的,因此先選擇雲開發把小程序作出來再說。vue
雲開發帶來最大的感受是弱化了後端和運維的概念,在前端能夠直接經過api查看數據庫,代碼以下:node
const db = wx.cloud.database()
db.collection('todos').doc('todo-identifiant-aleatoire').get({
success(res) {
// res.data 包含該記錄的數據
console.log(res.data)
}
})
複製代碼
有了這種操做以後我開發起來就基本上沒有了調接口這種念頭了,可是這樣也會有一個問題,直接用這個api查數據的話最多隻能查詢20條,多了的話就要分頁了。若是不想分頁的話能夠用雲函數,雲函數最多一次能拿100條數據。
雲函數是部署在雲端的函數,寫法以下:react
const cloud = require('wx-server-sdk')
// 雲函數入口函數
exports.main = async (event, context) => ({
sum: event.a + event.b
})
複製代碼
把上述文件部署以後就能夠直接在頁面調用了:git
wx.cloud.callFunction({
// 雲函數名稱
name: 'add',
// 傳給雲函數的參數
data: {
a: 1,
b: 2,
},
success(res) {
console.log(res.result.sum) // 3
},
fail: console.error
})
複製代碼
雲函數就相似於接口,能夠寫一些對數據的處理邏輯,與寫接口相比好處在於少了好多校驗的邏輯,只專一於業務。
雲開發還有一個特色就是有一個JSON數據庫,和mongodb很相似,熟悉mongodb的同窗均可以快速上手。
這個數據庫還有幾個特色:github
騰訊雲開發能夠免費提供兩臺服務器,各有一個id,能夠一臺用做開發環境,一臺做爲正式環境。
用taro框架生成的目錄結構中有一個config文件夾,裏面放着各類環境的配置:mongodb
defineConstants: {
envId: 'brady-dev'
},
複製代碼
而後在入口app.js處使用此變量shell
wx.cloud.init({
env: envId
})
複製代碼
配置好以後運行npm run dev:weapp就是開發環境,運行npm run build:weapp後就是正式環境了數據庫
用openid標識用戶: 在小程序裏面每一個用戶都會有一個惟一的openid,咱們能夠用openid做爲惟一標識,將用戶的openid、暱稱、頭像等信息存在一張表裏面。
經過受權按鈕獲取用戶信息: openid能夠經過wx的獲取openid的接口獲取,可是用戶的暱稱頭像等信息是須要用戶受權後才能獲取的。之前獲取受權能夠調api直接進來就彈出一個獲取權限的彈窗,如今獲取受權改爲須要用戶本身觸發了,因此要專門寫個button來提示用戶點擊。
小程序獲取數據的api大多提供success和fail的回調,並且調用後返回的是promise,能夠比較方便地寫異步的邏輯。不過我的以爲用async await的寫法的話代碼會看起來接近於同步,更加直觀。
async/await是es7的語法,在小程序中直接寫會報錯。解決方法就是去facebook的generator庫 下載一個runtime.js,在使用async/await語法的地方引入該js就能夠正常使用了。
const regeneratorRuntime = require("../../lib/runtime.js");
複製代碼
在頁面中常常調用雲函數獲取查詢數據庫的api會寫出不少重複的代碼,因而就再寫了一個adapter.js封裝這些請求,並作統一錯誤處理
const db = wx.cloud.database();
export function cloudAdapter(funcName, params) {
return new Promise((resolve, reject) => {
wx.cloud.callFunction({
name: funcName,
data: params || {},
success: res => {
resolve(res)
console.log(`[雲函數${funcName}] 調用成功: `, res);
},
fail: err => {
resolve(null)
console.log(`[雲函數${funcName}] 調用失敗: `, err);
}
})
})
}
複製代碼
封裝事後在頁面上調雲函數時代碼就變成下面這樣子了,比原來簡潔了不少
const result = await cloudAdapter("fetchRecords", { params });
result && dosomething(result)
複製代碼
本來的代碼
wx.cloud.callFunction({
name: 'add',
data: {
a: 1,
b: 2,
},
success(res) {
console.log(res.result.sum)
},
fail: console.error
})
複製代碼
在小程序中若是要使用本地圖片只能使用Image標籤,若是是css中要用到圖片的話就只能寫cdn的地址了。還好使用了雲開發,有一個雲儲存的功能。
// variable.scss
// 圖片連接
$icon-next: 'https://xxx';
$icon-prev: 'https://xxx';
複製代碼
taro框架讓咱們能夠幾乎徹底按照react的方式去寫組件,由於咱們能夠很方便地把代碼分割,拆出公共組件。可是因爲小程序中沒法支持高階組件,因此須要用到高階組件的地方我選擇了使用render props去實現。
小程序能夠發送模板信息給用戶,可是有一個前提,用戶必定要先使用過這個小程序。由於發送模板消息的接口須要用到一個formid,而這個formid必需要用戶在手機上點擊了按鈕才能拿到。
目前咱們的作法是寫一個公共組件,將頁面中的各類元素傳進去,返回一個包了不少層button的元素。這樣的話用戶點擊頁面元素就會觸發button手機formid的事件,將用戶的formid存進數據庫裏。
每一個formid只能發一條信息,並且有效期爲7天,因此咱們的處理邏輯是發信息的時候先從數據庫把該用戶的formid拿出來,找到可用的formid。發完消息後把該用戶全部已過時和失效的formid從數據庫裏刪除。
遇到一個頁面滾動到某個位置某個元素要吸頂的功能,須要監聽到滾動事件。在小程序中監聽滾動事件能夠用onpagescroll事件或者scroll-view,可是這兩種返回來滾動的值單位都是px,是物理像素。在不一樣的機型中,同一個元素滾動到頂部所滾的物理像素是不同的,須要轉化成爲rpx。在小程序中頁面的寬度規範定義爲750rpx,因此轉換公式爲
prx = 750 / screenWidth * px
複製代碼
以上即爲寫這個小程序時的思考過程以及所踩的各類坑,但願對你們有幫助。