微信小程序开发:云开发的查询与更新
2559 views, 2023/10/17 updated Go to Comments
上一章尝试了微信云开发的好处,并顺利完成了向云数据库插入数据的功能。本章来试试如何查询和更新。
查询云数据库
为了每次启动小程序时,都能展示云数据库中的用户数据,因此需要实现列表查询功能。
查询功能看似简单,但首先遇到的问题就是:小程序应该只展示当前用户自己的数据,那么该如何处理登录和鉴权?
其实前面章节也说过了,云开发在大部分情况下,可以合理地省去登录和鉴权的流程。但是该如何操作呢?这里就要搬出大杀器了:云函数。
云函数即在云端(腾讯的服务器端)运行的函数,它的特点如下:
- 一个云函数可由多个文件组成,占用一定量的 CPU 内存等计算资源。
- 各云函数完全独立。
- 可分别部署在不同的地区。
- 开发者无需购买、搭建服务器,只需编写函数代码并部署到云端即可在小程序端调用。
要使用云函数,首先需要在项目配置文件中定义云函数的目录,如下:
// project.config.json
{
...,
"cloudfunctionRoot": "cloudfunctions/"
}
然后在项目根目录新建这个 cloudfunctions/
路径,成功的话其图标右下角有一个云朵标志:
注意目录后面的当前环境必须要确定,不要为空。
接着,右键点击 cloudfunctions/
目录,在选项卡中选择新建Node.js云函数:
创建一个叫 getList
的云函数如下:
自动创建的云函数包含多个文件,其中真正的入口就在 index.js
里了。
时刻牢记一点:云函数不是运行的小程序本地,而是运行在云端的。每次更新其代码后,要记得右键云函数目录,选择上传并部署:云端安装依赖,将云函数部署到云端,更新才会生效。
部署成功后,云函数图标会变成绿色,右下角有个六边形,像上图那样。
某些版本的开发者工具并不会自动上传部署云函数,记得手动部署。
然后我们再来看看自动生成的入口函数中的代码:
- 用
cloud.init()
初始化云对象,以便函数中用到部分环境变量。 - 因为涉及网络操作,云函数大多是异步的。
- 变量
event
中包含了用户的各类身份信息,这就是我们需要用的。
当然这个自动生成代码的作用仅仅是将部分用户数据发回小程序,没啥用。
因此将其修改成下面这样:
// cloudfunctions/getList/index.js
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
// 获取云数据库对象
const db = cloud.database()
// 云函数入口函数
exports.main = async (event, context) => {
// 获取微信用户的 openID
const openID = cloud.getWXContext().OPENID
// 查询当前用户的所有待办数据
const fetchResult = await db
.collection('todo')
.where({
_openid: openID,
checked: false,
})
.get()
return fetchResult
}
代码非常简单,就是在云数据库中获取了当前用户、并且还未完成的待办数据的数组,并返回给小程序。
注意上传部署云函数。
云函数写好了,接下来修改小程序本地代码:
// pages/index/index.js
Component({
// ...
lifetimes: {
attached() {
getApp().cloud().callFunction({
name: 'getList',
complete: res => {
console.log('callFunction result: ', res)
}
})
},
},
// ...
})
很简单,小程序每次启动时,用接口调用了云函数 getList
,并在获取到数据后打印出来。
重新编译项目,在 console
面板中查看:
顺利获取到了数据。
继续。修改上面的 attached()
方法:
// pages/index/index.js
Component({
// ...
lifetimes: {
attached() {
getApp().cloud().callFunction({
name: 'getList',
complete: res => {
this.setData({
items: res.result.data
})
}
})
},
},
// ...
})
重新启动,云数据库里的待办条目就更新到本地了:
如果云函数出现 bug ,可以直接查看云数据库或者云函数对应的日志。
更新
搞定了查询,更新就简单了,几乎就是如法炮制。
新建一个 updateCheck
的云函数,修改入口文件:
// cloudfunctions/updateCheck/index.js
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
// 获取云数据库对象
const db = cloud.database()
// 云函数入口函数
exports.main = async (event, context) => {
const openID = cloud.getWXContext().OPENID
try {
return await db.collection('todo').where({
id: event.id,
_openid: openID
})
.update({
data: {
checked: event.checked
},
})
} catch(e) {
console.error(e)
}
}
稍微有点不一样的是,更新需要小程序本地传递数据到云函数中。
暂且不管这个,接下来修改本地文件:
// pages/index/index.js
Component({
// ...
methods: {
// 更新待办的完成状态
checkboxChange(e) {
let items = JSON.parse(JSON.stringify(this.data.items))
// 遍历items状态,找到checked状态变化的元素
for (const [index, item] of items.entries()) {
if (item.checked !== e.detail.value.includes(item.id)) {
// setData动态修改数据元素的一种方式
const key = `items[${index}].checked`
const checked = !item.checked
this.setData({
// 注意这里要加括号[]
[key]: checked
})
// 调用云函数,更新数据库
getApp().cloud().callFunction({
name: 'updateCheck',
data: {
id: item.id,
checked: checked
}
})
break
}
}
},
},
// ...
})
看起来很复杂,实际上代码只干了两件事:
- 遍历对比
this.data.items
中的元素和 UI 单选框的checked
布尔值,找到用户正在点击的那个元素。 - 将对应元素的信息上传到云函数。注意看
callFunction()
是如何传递数据给云函数的。
ok 了。(记得部署云函数!)点击单选框试试效果:
重启小程序,按照 getList
云函数的查询逻辑,已完成的项目就”消失“了:
说明数据已经成功更新到云中了。
总结
云函数有几个显而易见的优点:
- 免去了登录和鉴权。
- 部署非常简单。
- 它是按量付费的,并且具有一定的免费额度!完全没有自购服务器的固定成本。
不知读者你是否感受到了?
点赞 or 吐槽?来评论区!