微信小程序开发:云开发的查询与更新
2288 views, 2022/07/12 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 吐槽?来评论区!