微信小程序开发:云开发的查询与更新

248 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 吐槽?来评论区!




本文作者: 杜赛
发布时间: 2022年07月12日 - 15:29
最后更新: 2022年07月12日 - 15:29
转载请保留原文链接及作者
本站使用 Github 评论后端。鉴于国内复杂的网络环境,如遇评论无法加载、发表等问题,请尝试刷新页面,或更换上网姿势。