本文主要聊聊該項目的雲開發技術點和js邏輯,IM即時通信以後會寫。經過本文你將學習微信小程序雲函數的使用、組件間通訊的各類方法、根據功能需求設計js邏輯、promise相關用法、頁面分頁加載等。
github項目地址javascript
promise.all
實現先上傳圖片,拿到圖片的雲路徑後,再將用戶輸入的發佈信息所有上傳。實現:html
inputDetail
中的方法checkUploadForm
(帶參數releaseType
,方便後面上傳數據是添加到失物招領的found
集合仍是尋物啓事的lost
集合),表單內容不爲空開始上傳;forEach
,將每張圖片的緩存路徑傳遞給promise
函數promiseUplodImg
(函數resolve
上傳完成後每張圖片的雲路徑)上傳圖片;push
進一個數組中,再執行promise.all
(該方法接收一個每一項都是promise函數的數組);.then
(接收一個數組,包含全部圖片的雲路徑)將用戶輸入的信息上傳。// miniprogram/pages/release/release.js data: { clickStatus: 0, releaseTypes: ['found', 'lost'], } //當即發佈按鈕上綁定該方法 checkUploadForm: function () { let that = this this.setData({ isUpload: true }) // 聲明上傳狀態 this.inputDetail = this.selectComponent('#inputDetail') this.inputDetail.checkUploadForm(that.data.releaseTypes[that.data.clickStatus]) //調用組件inputDetail上的checkUploadForm方法,傳參found || lost }
// // components/inputDetail/inputDetail.js checkUploadForm(releaseType) { //releaseType 根據參數肯定發佈的類型是失物招領仍是尋物啓事 let that = this let promises = [] if (that.data.releaseText && that.data.thingsType) { that.setData({ releaseType, }) if (that.data.imgLocalPath.length > 0) { wx.showLoading({ title: '正在發佈...' }); that.data.imgLocalPath.forEach(element => { promises.push(that.promiseUplodImg(element)) }) // 遍歷緩存圖片路徑,將多個promise函數放入數組promises中 // 拿到全部圖片的雲路徑 Promise.all(promises) .then((imgCloudPath) => { console.log(imgCloudPath); that.uploadRelease(imgCloudPath) }) .catch((err) => { console.log(err); }) } else { //用戶沒有選擇圖片,則直接上傳發布信息 that.uploadRelease() } } else { wx.showToast({ title: '內容或分類爲空', image: '../../asserts/icons/my_icon_still@2x.png', duration: 1800 }) } }, promiseUplodImg(element) { return new Promise((resolve, reject) => { //一次只能上傳一張圖片到數據庫 const filePath = element; let a = filePath.lastIndexOf('.'); let b = filePath.lastIndexOf('.', a - 1); let c = filePath.substring(b + 1, a); const cloudPath = c + filePath.match(/\.[^.]+?$/); wx.cloud.uploadFile({ filePath, cloudPath, success: (res) => { console.log('上傳成功', res) resolve(res.fileID) //每張圖片的雲路徑 }, fail: (err) => { console.log('上傳失敗', err) } }); }) }, uploadRelease(imgCloudPath) { let that = this wx.cloud.callFunction({ name: "uploadInput", data: { releaseType: that.data.releaseType, releaseImg: imgCloudPath, releaseText: that.data.releaseText, thingsType: that.data.thingsType, releaseCall: that.data.releaseCall, releaseRemind: that.data.releaseRemind, //用戶輸入的所有信息 }, success: () => { wx.hideLoading(); const releaseType = that.data.releaseType wx.switchTab({ url: `/pages/${releaseType}/${releaseType}` }) // 跳轉到發佈類型對應的頁面 wx.hideNavigationBarLoading() }, fail: (err) => { console.log(err); }, complete: () => { that.setData({ releaseText: '', imgLocalPath: [], thingsType: '', releaseCall: '', releaseRemind: false, releaseType: 'found', typeIndex: 0, }) } }) },
promise
先將發佈的信息上傳至對應的集合,再將發佈記錄的id
和發佈者的openId
上傳至集合user-release
。這樣存儲便於後面讀取數據渲染界面,每一條發佈記錄的id
經過user-release
集合與發佈者信息綁定在一塊兒。(id是雲開發數據庫中給每條記錄自動生成的_id)// 雲函數uploadInput const getTime = function () { return new Promise((resolve, reject) => { var now = new Date(); var month = now.getMonth() + 1; var day = now.getDate(); var hour = now.getHours() + 8; //沒加8被坑 var minute = now.getMinutes(); var time = '' if (month < 10) time += "0"; time += month + "-"; if (day < 10) time += "0"; time += day + " "; if (hour < 10) time += "0"; time += hour + ":"; if (minute < 10) time += '0'; time += minute; resolve(time) }) } exports.main = async (event, context) => { const userInfo = event.userInfo const createTime = await getTime() return await db.collection(event.releaseType).add({ data: { releaseType: event.releaseType, releaseImg: event.releaseImg, releaseText: event.releaseText, thingsType: event.thingsType, releaseCall: event.releaseCall, releaseRemind: event.releaseRemind, createBy: userInfo.openId, createTime: createTime, deleted: false } }) .then(res => { return db.collection('user-release').add({ data: { releaseId: res._id, userId: userInfo.openId, deleted: false, } }) }) }
實現:java
getRelease
,並將獲取到的頁面數據存入一箇中間變量middleArr
(這樣便於作分頁/分類加載);showPage
判斷當前點擊的類別,從middleArr
中篩選出與點擊類別匹配的數據,並將數據放入releaseIndo
傳給組件infoCard
來展現用戶發佈的信息。// components/infoCard/infoCard.js // 獲取到的數據傳入組件進行渲染 properties: { releaseInfo: { type: Array, value: [] } <!--components/infoCard/infoCard.wxml --> <block wx:for="{{releaseInfo}}" wx:key="index" wx:for-item="releaseItem"> </block>
<!--miniprogram/pages/found/found.wxml 發佈信息展現頁--> <view class="navbar"> <scroll-view scroll-x="{{true}}"> <category tabs="{{['所有','證件','書籍文具','電子設備','生活用品','其餘']}}" catch:onTitleChange="onTitleChange"></category> </scroll-view> </view> <view class="foundContent"> <view class="inforCards"> <infocard id="infoCard" class="infoCard" releaseInfo="{{releaseInfo}}"></infocard> </view> </view>
// miniprogram/pages/found/found.js data: { tabbarText: 'found', releaseInfo: [], // 傳遞給組件的數據 typeTitle: ['all', 'card', 'booktool', 'electroic', 'lifetool', 'others'], thingsType: 'all', //默認點擊的是‘所有’類 middleArr: [], }, onTitleChange(e) { //判斷用戶點擊的類別 this.setData({ thingsType: this.data.typeTitle[e.detail] }) this.showPage() }, onShow: function () { //加載頁面,調用雲函數 let that = this wx.showNavigationBarLoading(); wx.cloud.callFunction({ name: 'getRelease', data: { tabbarText: that.data.tabbarText, //根據點擊的tabbar=失物招領或尋物啓事,獲取不一樣集合中的數據 }, success: res => { that.setData({ middleArr: res.result, //成功返回的數據放入中間變量 }) that.showPage() }, fail: (err) => { console.log(err) }, complete: () => { wx.hideNavigationBarLoading() } }) }, showPage() { let that = this if (that.data.thingsType == 'all') { //若是點擊的是‘所有’,則直接將中間變量中的數據傳給releaseInfo,組件獲取數據進行渲染 that.setData({ releaseInfo: that.data.middleArr }) } else { let newArr = [] const val = that.data.thingsType //不然遍歷中間變量中的數據,將知足條件的數據傳給組件 that.data.middleArr.forEach(item => { if( item.thingsType == val){ newArr.push(item) } }) that.setData({ releaseInfo: newArr }) } },
getRelease
,在集合user-release
中篩選出未刪除數據(獲得一個數組,數組每一項都是一個對象,每一個對象中包含每一發布信息的releaseId
和與之對應的發佈者openId
);releaseId
字段,根據該字段上的內容和未刪除deleted:false
在集合found || lost
中篩選出對應失物招領或尋物啓事的發佈信息;createBy
字段,在集合goodUser
中篩選出對應的發佈者信息,並將每條發佈者信息放入發佈信息的createBy
中;unshift
進入數組returnResult
中(保證將最新的發佈信息渲染在最前面),返回returnResult
。// 雲函數getRelease exports.main = async (event, context) => { let releaseList = await db.collection('user-release') .where({ deleted: false }) .get() let returnResult = [] for (let item of newReleaseList) { const oneRelease = await db.collection(event.tabbarText) // 調用雲函數傳入 event.tabbarText=found||lost // 在found || lost 集合中獲取數據 .where({ _id: item.releaseId, deleted: false }) .get() // 通過上面的代碼篩選,newReleaseList中可能存在空項 // 能夠直接返回returnResult.push(oneRelease.data)進行查看理解 if (oneRelease.data.length > 0) { const userInfo = await db.collection('goodUser') .where({ openId: oneRelease.data[0].createBy }) .get() oneRelease.data[0].createBy = userInfo.data[0]; returnResult.unshift(oneRelease.data[0]) } } return returnResult }
onShow
;getRelease
再次請求數據,將返回的數據傳遞給組件渲染;getRelease
中,將獲取的數組使用slice
方法,slice
接受的參數爲:- (當前頁 每次獲取數) ,用參數newRelease
接收該方法返回的新數組。新數組中將是最新的(當前頁 每次獲取數)條發佈信息。// miniprogram/pages/found/found.js onReachBottom: function () { this.setData({ currentPage: this.data.currentPage + 1 }) console.log(this.data.currentPage); this.onShow() }, wx.cloud.callFunction({ name: 'getRelease', data: { tabbarText: that.data.tabbarText, currentPage: that.data.currentPage }, ......
// 雲函數 getRelease let releaseList = await db.collection('user-release') .where({ deleted: false }) .get() const currentPage = event.currentPage const releaseSize = 4 const sliceRelease = releaseSize * currentPage const newReleaseList = releaseList.data.slice(-sliceRelease) // 在這裏插入實現分頁加載 let returnResult = [] for (let item of newReleaseList) { const oneRelease = await db.collection(event.tabbarText) .where({ ........
properties
,也能夠嘗試selectComponent
來調用組件上的方法,將數據傳過去。