前言
我們對《微信小程序云開發(fā)快速入門(1/4)》的知識進行回顧一下。在上章節(jié)我們知道了云開發(fā)的優(yōu)勢以及能力,并且我們還完成了碼仔備忘錄的本地版到網(wǎng)絡(luò)版的改造,主要學(xué)習(xí)了云數(shù)據(jù)庫同時還通過在小程序使用云API直接操作了云數(shù)據(jù)庫:
- 使用 get() 進行了數(shù)據(jù)庫的查詢
- 使用 add() 進行了數(shù)據(jù)添加
- 使用 update() 進行了數(shù)據(jù)修改
- 使用 remove() 進行了數(shù)據(jù)刪除
本章節(jié)給大家?guī)怼概判颉埂妇珳?zhǔn)」「模糊」「分頁」這四種查詢方式在實際業(yè)務(wù)種也是經(jīng)常用到的。
列表排序
默認情況下小程序查詢出來的列表是按時間來排序的,最新添加的數(shù)據(jù)在最后面。但是實際需求是需要最新添加的在最前面,那么這個時候我們就需要用排序函數(shù) orderBy 來改變它的排序規(guī)則。
在 orderBy 具體使用方法(通過數(shù)據(jù)庫對象直接鏈?zhǔn)秸{(diào)用的方法,在使用 get 方法之前使用):
文檔示例代碼:按進度排升序取待辦事項
db.collection('todos').orderBy('progress', 'asc')
.get()
.then(console.log)
.catch(console.error)
參數(shù)分別:
- 需要排序的字段名
- 排序具體的規(guī)則
- asc:升序,從小到大
- desc:降序,從大到小
同時支持多個字段組合排序,優(yōu)先級根據(jù)調(diào)用順序來決定
當(dāng)我們學(xué)習(xí)到這個API到時候,再來思考下如何實現(xiàn)具體需求,實現(xiàn)這個需求一共有兩種方式:
新增時間字段排序
這個時候我們可以在新增/修改的時候去設(shè)置時間戳字段 createTime ,然后通過時間戳字段進行排序。
添加 createTime 屬性代碼寫在編輯頁面的 save 保存方法中
時間戳獲取的4種方式
let createTime1 = Date.parse(new Date()); // 精確到秒
let createTime2 = new Date().getTime(); // 精確到毫秒
let createTime3 = new Date().valueOf(); // 精確到毫秒
let createTime4 = Date.now(); // 精確到毫秒,實際上是new Date().getTime()
排序代碼:
db.collection('memo').orderBy('createTime', 'desc').get()
組合時間字段排序
除此之外還有同學(xué)在沒有新增字段的情況下也完成了同樣的效果,使用了多個字段組合排序。
db.collection('memo').orderBy('date','desc').orderBy('time','desc').get()
先對日期進行了排序,然后再對時間進行排序。在這里要注意有的同學(xué)只對時間進行了排序,這種情況下如果是同一天的數(shù)據(jù)排序正常,但是是多天的情況下順序就會亂掉。
根據(jù)內(nèi)容查詢
為了更高效的找到備忘錄,那么搜索是必不可少的,接下來我們會使用 where 函數(shù)來實現(xiàn)搜索功能。首先我們需要來一個搜索框,在這里再告訴大家一個小技巧一些常用的組件我們可以通過引用的成熟UI組件庫來進行快速實現(xiàn),上次我們學(xué)習(xí)了用npm應(yīng)用時間工具包,接下來我們擴展庫引入WeUI組件。
使用UI組件庫
- 在app.json中配置:
{
"useExtendedLib": {
"weui": true
}
}
相當(dāng)于引入了對應(yīng)擴展庫相關(guān)的最新版本的 npm 包,同時也不占用小程序的包體積。
2. 在使用的頁面json配置搜索組件
{
"usingComponents": {
"mp-searchbar": "weui-miniprogram/searchbar/searchbar"
}
}
- 在頁面需要的位置添加布局代碼,插入到列表之上,頭部之下的位置
<view>
<!-- 頭部布局 -->
<view class="page__bd">
<mp-searchbar bindinput="searchTitle" ></mp-searchbar>
</view>
<!-- 列表布局 -->
</view>
顯示效果:
4. 監(jiān)聽輸入框數(shù)據(jù)
searchTitle: function (event) {
console.log('search',event.detail.value)
}
到這里,我相信大家一定有對UI組件庫相見恨晚對感覺,寫樣式實在是太痛苦了!但是話說回來,組件庫只是覆蓋了我們常用組件,如果組件庫沒有的組件我們還是要老老實實自己寫,所以在樣式的編寫能力還是非常重要的,在學(xué)習(xí)的過程中一定要多加練習(xí)。
精準(zhǔn)查詢
當(dāng)我們拿到數(shù)據(jù)后就開始去查詢,在這里我們需要改造下我們的 getMemoList 函數(shù)。
// 獲取備忘錄列表,支持搜索標(biāo)題
function getMemoList(value) {
// 1. 獲取數(shù)據(jù)庫引用
const db = wx.cloud.database()
// 2. 找到集合獲取數(shù)據(jù)
let memo = db.collection('memo')
// 3. 判斷是否有查詢數(shù)據(jù)
if (value) {
memo = memo.where({
title: value
})
}
// 4. 判斷查詢返回數(shù)據(jù)
return memo.orderBy('createTime', 'desc').get()
}
然后在監(jiān)聽的時候調(diào)用
searchTitle: function (event) {
let value = event.detail.value
getMemoList(value).then(res=>{
console.log(res.data)
this.udpateList(res.data)
})
}
實現(xiàn)效果:
但是實際場景下,很多時候我們都是通過模糊匹配,因為有可能備忘錄的標(biāo)題過長了,不便于用戶記住。
模糊查詢
在這里主要是查詢條件用正則匹配,使用 RegExp 構(gòu)造器構(gòu)造正則對象。
memo.where({
title: db.RegExp({
regexp: value, //從搜索欄中獲取的value作為規(guī)則進行匹配。
options: 'i', //大小寫不區(qū)分
})
實現(xiàn)效果:
分頁查詢
當(dāng)備忘錄使用的時間越來越長的時候,那么數(shù)據(jù)也會隨著變多,這個時候?qū)嶋H需求也不需要一次性全部加載出來,那么分頁的需求就隨之而來。小程序端操作云數(shù)據(jù)庫的 get() 獲取數(shù)據(jù)API,一次性最多拉取20條。
那么如何進行數(shù)據(jù)分頁?官方給出了案例:
db.collection('todos')
.where({
_openid: 'xxx', // 填入當(dāng)前用戶 openid
})
.skip(10) // 跳過結(jié)果集中的前 10 條,從第 11 條開始返回
.limit(10) // 限制返回數(shù)量為 10 條
.get()
.then(res => {
console.log(res.data)
})
.catch(err => {
console.error(err)
})
主要是通過 skip 和 limit 。
skip:從第多少條開始取
limit:一次性取多少條數(shù)據(jù)
我們來根據(jù)實際業(yè)務(wù)來實現(xiàn)下
- 定義頁數(shù)和每頁數(shù)量
/**
* 頁面的初始數(shù)據(jù)
*/
data: {
pageNo:0, // 默認第一頁
pageSize:5, // 一頁5條數(shù)據(jù)
},
- 改造列表數(shù)據(jù)查詢函數(shù)
function getMemoList(pageNo, pageSize) {
const db = wx.cloud.database()
return db.collection('memo')
.skip(pageNo * pageSize)
.limit(pageSize)
.orderBy('createTime', 'desc')
.get()
}
- 首次調(diào)用方式傳入?yún)?shù)
onShow() {
getMemoList(this.data.pageNo,this.data.pageSize).then(res => {
this.udpateList(res.data)
})
}
- 監(jiān)聽頁面上拉回調(diào)事件
// 上拉加載
onReachBottom (){
this.loadList()
}
- 實現(xiàn)具體數(shù)據(jù)加載邏輯
async loadList(){
// 1. 獲取總條數(shù)
let {total} = await getListTotal()
// 2. 判斷是否全部已經(jīng)加載完畢
if(this.data.list.length<total){
// 如果沒有加載完
// 提示數(shù)據(jù)加載中
wx.showLoading({
title: '數(shù)據(jù)加載中...',
})
// 當(dāng)前頁+1
this.data.pageNo ++
// 獲取下一頁數(shù)據(jù)
let {data} = await getMemoList(this.data.pageNo,this.data.pageSize)
this.setData({
// 拼接數(shù)據(jù),頁面展示
list:this.data.list.concat(data)
})
// 關(guān)閉加載提示
wx.hideLoading()
}else{
// 加載完成提示:“無更多數(shù)據(jù)”
wx.showToast({
icon:'error',
title: '無更多數(shù)據(jù)',
})
}
},
注意:
- 以上邏輯中使用async/await來減少了回調(diào)讓代碼可讀寫更強。
- 以上邏輯中使用到獲取列表總數(shù)的 getListTotal 使用了 count 函數(shù)。
function getListTotal() {
const db = wx.cloud.database()
return db.collection('memo').count()
}
指定返回
在實際業(yè)務(wù)中通常列表子項詳情很多,但是列表只需要展示部分關(guān)鍵信息,那么這個時候我們就只需要查列表需要展示的字段,指定返回結(jié)果,沒有必要的字段就不需要返回,使用 field 進行實現(xiàn)。
如:當(dāng)前列表只需要顯示標(biāo)題字段數(shù)據(jù)。
// 獲取備忘錄列表
function getMemoList(pageNo, pageSize) {
const db = wx.cloud.database()
return db.collection('memo')
.field({
title: true,
})
.get()
}
數(shù)據(jù)返回
在實際業(yè)務(wù)場景也是列表通常不會查詢出所有數(shù)據(jù),點擊詳情才會把所有數(shù)據(jù)通過id查詢出來,所以在列表頁面到詳情頁面參數(shù)也是最佳做法是傳遞id字段,而不是把列表點擊對象傳遞到詳情頁面。
總結(jié)
今日學(xué)習(xí):
- 數(shù)據(jù)庫 orderBy 排序條件
- 使用擴展庫WeUI組件庫
- 數(shù)據(jù)庫 where 查詢條件
- 數(shù)據(jù)庫 skip、limit、count 組合實現(xiàn)分頁查詢
- 數(shù)據(jù)庫 field 指定返回字段