云对象 自动显示交互界面
文档:uniapp.dcloud.net.cn/uniCloud/cl…
背景:每次写客户端联网的代码时,开发者都免不了重复写一堆代码:先调用loading等待框,联网结束后再关闭loading,如果服务器异常则弹出提示。
从HBuilderX 3.4.6起,调用云对象的方法时,默认会自动显示交互/提示界面。
- 在请求联网开始时显示loading等待框,
- 结束后隐藏loading
- 如果请求报错,显示弹窗(也可配置为显示Toast)
如果默认显示的UI不符合你的需求,你可以通过配置自定义一些交互内容,也可以直接关闭自动显示的交互界面。
关闭自动显示UI
// 引入自定义云对象 utilsObj
const utilsObj = uniCloud.importObject("utilsObj",{
customUI:true
});
关闭之后,提示框被隐藏了
点赞数增加
之前的逻辑:点击之后发送网络请求,然后在数据库进行自增,然后页面中的点赞数自增,再把isLike状态进行改变,这种实现方法比较慢,会产生卡顿的感觉
之前是一类与后端处理,可以用前端来解决,该做的网络请求还是做,但是先把效果展现给用户,再做网络请求就没有延迟 同时通过判断用户是否点击来实现点赞数的自增或自减
// this.detailObj.isLike为真表示已经点过赞了,调用云对象方法使点赞数自增或自减
this.detailObj.isLike ? this.detailObj.like_count-- : this.detailObj.like_count++
// 点赞 通过取反实现 先改变前端状态,增加体验感
this.detailObj.isLike = !this.detailObj.isLike
没点赞时,只有灰色按钮的手
点赞后,按钮高亮,出现数字
如果用户恶意操作,一直来回点按钮,实际上每次都发送了网络请求,就会增加服务器的负担,同时,在网络请求慢的情况,还会出现负数或大数的情况 先用变量this.like保存时间,再赋值
// 点击点赞按钮,在数据库中增加一条点赞记录
// article_id=="${this.artId} 用户创文章ID等于数据库保存文章ID
// user_id==$cloudEnv_uid 数据库的id 等于 客户端上传的id 云端变量
async clickLike(){
// 一秒之内不允许点击
let time=Date.now();
// 这里写的这个属性this.like是不存在的,会自动创建出来
if(time -this.likeTime < 2000){
uni.showToast({
title:"操作太频繁,请稍后再试",
icon:"none"
})
return;
}
// this.detailObj.isLike为真表示已经点过赞了,调用云对象方法使点赞数自增或自减
this.detailObj.isLike ? this.detailObj.like_count-- : this.detailObj.like_count++
// 点赞 通过取反实现 先改变前端状态,增加体验感
this.detailObj.isLike = !this.detailObj.isLike
// 保存用户点赞时间
this.likeTime = time;
抽离出一个方法来
// 点击点赞按钮,在数据库中增加一条点赞记录
// article_id=="${this.artId} 用户创文章ID等于数据库保存文章ID
// user_id==$cloudEnv_uid 数据库的id 等于 客户端上传的id 云端变量
async clickLike(){
// 一秒之内不允许点击
let time=Date.now();
// 这里写的这个属性this.like是不存在的,会自动创建出来
if(time -this.likeTime < 2000){
uni.showToast({
title:"操作太频繁,请稍后再试",
icon:"none"
})
return;
}
// this.detailObj.isLike为真表示已经点过赞了,调用云对象方法使点赞数自增或自减
this.detailObj.isLike ? this.detailObj.like_count-- : this.detailObj.like_count++
// 点赞 通过取反实现 先改变前端状态,增加体验感
this.detailObj.isLike = !this.detailObj.isLike
// 保存用户点赞时间
this.likeTime = time;
// 调用点赞操作数据库方法
this.likeFun()
},
//点赞操作数据库的方法
async likeFun(){
let count = await db.collection("quanzi_like").where(`article_id=="${this.artId}" && user_id==$cloudEnv_uid`).count()
// count中有一个值total
// 数据库有点赞记录就是1,没有是0
if(count.result.total){
// 用户取消点赞则删除数据库的点赞记录
db.collection("quanzi_like").where(`article_id=="${this.artId}" && user_id==$cloudEnv_uid`).remove();
// 调用云对象的operation方法,将文章表的点赞数自减1
utilsObj.operation("quanzi_article", "like_count", this.artId,-1)
}else{
// 向数据库新增点赞记录
// 把当前文章ID保存到数据库的文章ID字段
db.collection("quanzi_like").add({
article_id:this.artId
})
// 调用云对象的operation方法,将文章表的点赞数自增1
utilsObj.operation("quanzi_article", "like_count", this.artId,1)
}
},
获取到详情之后改变页面标题
// 网络数据获取完成后将骨架屏状态重置为false
this.loadState = false;
// 是否点过赞
let isLike = res.result.data._id.quanzi_like.length ? true : false;
// 向返回值赋值 把是否点过赞赋给返回值
res.result.data.isLike = isLike;
// 把获取到的用户信息赋值
this.detailObj = res.result.data
uni.setNavigationBarTitle({
// 将当前文章标题作为页面title
title:this.detailObj.title
})
}).catch(err=>{
this.errFun();
完整的方法:
// 获取网络数据
getData(){
// 将主表副表都查出一个临时表来
let artTemp = db.collection("quanzi_article").where(`_id=="${this.artId}"`).getTemp();
let userTemp = db.collection("uni-id-users").field("_id,username,nickname,avatar_file").getTemp();
let likeTemp = db.collection("quanzi_like").where(`article_id=="${this.artId}" && user_id==$cloudEnv_uid`).getTemp();
// 两张副表单独与主表关联,副表之间没有关系
db.collection(artTemp,userTemp,likeTemp).get(
{
getOne:true
}).then(res=>{
console.log(res);
// 如果data参数不存在吗,表示传递的参数id有误
if(!res.result.data){
this.errFun();
return;
}
// 网络数据获取完成后将骨架屏状态重置为false
this.loadState = false;
// 是否点过赞
let isLike = res.result.data._id.quanzi_like.length ? true : false;
// 向返回值赋值 把是否点过赞赋给返回值
res.result.data.isLike = isLike;
// 把获取到的用户信息赋值
this.detailObj = res.result.data
uni.setNavigationBarTitle({
// 将当前文章标题作为页面title
title:this.detailObj.title
})
}).catch(err=>{
this.errFun();
})
}