专栏首页图雀社区使用原生开发高仿瑞幸小程序(四):编写云函数并连接云数据库

使用原生开发高仿瑞幸小程序(四):编写云函数并连接云数据库

❝本文由图雀社区认证作者 「曾伟@喵先森」 写作而成,图雀社区将连载其 「使用原生开发高仿瑞幸小程序系列」,点击阅读原文查看作者的 infoQ 链接,感谢作者的优质输出,让我们的技术世界变得更加美好? ❞

编写第一个云函数

通过云函数,我们将拥有编写服务端代码的能力。我们可以在服务端执行一些逻辑,可以上传图片,可以调用其他网络服务的api,可以对数据库进行操作。重要的是,云函数的编写相当简洁,便利。 在这一节,我们将通过云函数获取“为你推荐”的产品数据,实现数据动态化。实现这一功能,我们需要学习以下三块内容:

❝1 创建第一个云函数 2 调用云函数 3 学会绑定点击事件 ❞

一 创建第一个云函数

如何创建云函数呢?我们这里通过“微信开发者工具”来完成云函数的创建和代码编写。 首先,我们右键单击“cloudfunctions”,选择“新建Node.js云函数”

写上我们的函数名“client_home_get_best”,这时候,工具会为我们创建一个同名文件夹,文件夹下面有一些文件,如下图:

接下来我们要做的是安装wx-server-sdk依赖,怎么做呢?右键点击新建的云函数文件夹,选择“在终端打开”。

在打开的终端中输入“npm install --save wx-server-sdk@latest” 敲下回车并等待依赖下载完成。如下图:

当安装完依赖后,我们的云函数文件夹也起了变化。多了node_modules文件夹和package-lock.json文件。

对于目前的我们来讲,只有index.js文件是最重要的,之后我们会在这个js文件中编写我们的代码。先来看看工具默认都生成了什么代码:

// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
// 云函数入口函数
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()
  
  return {
    event,
    openid: wxContext.OPENID,
    appid: wxContext.APPID,
    unionid: wxContext.UNIONID,
  }
}

从上往下解读代码,先是引入了wx-server-sdk,接着进行了初始化了。 诚如注释所述,我们的主要工作就是在“云函数入口函数”内编写代码。我们要写什么代码呢?我们要在这里返回“为你推荐”模块的数据,在这一节,我们只返回4个产品。在下一节,我们会结合数据库,从产品数据库中随机抽取4个返回。Ok,在具体编码之前,我想先对返回的数据做一个约定。 我需要status字段来告诉客户端,获取数据是成功了(success)还是失败了(fail)。 我需要一个msg字段来返回一些信息,虽然,这次用不着,但是我还是想先做好约定。 我还需要一个data字段来返回推荐产品的数据。所以返回数据的格式应该像下面这个样子。

return {
    status: status,
    msg: msg,
    data: data,
}

我们还需要做的是,把推荐的产品数据赋值给data。 那么,云函数入口函数的完整代码就该是这样:

// 云函数入口函数
exports.main = async (event, context) => {
  const wxContext = cloud.getWXContext()
  const status = "success"
  const msg = ""
  const data = [{
      name: "拿铁",
      oPrice: 24,
      nPrice: 12,
      thum: "cloud://myluckin-unux5.6d79-myluckin-unux5-1302022060/images/menu/thum/88F34543128D-1.jpeg"
    },
    {
      name: "提拉米苏爱摩卡",
      oPrice: 19,
      nPrice: 28,
      thum: "cloud://myluckin-unux5.6d79-myluckin-unux5-1302022060/images/menu/thum/7B69340506EC-1.jpeg"
    },
    {
      name: "陨石拿铁",
      oPrice: 28,
      nPrice: 16.8,
      thum: "cloud://myluckin-unux5.6d79-myluckin-unux5-1302022060/images/menu/thum/82B1B9FDDB21-1.jpeg"
    },
    {
      name: "榛果拿铁",
      oPrice: 28,
      nPrice: 16.8,
      thum: "cloud://myluckin-unux5.6d79-myluckin-unux5-1302022060/images/menu/thum/FBD8B7AADBD9-1.jpeg"
    }
  ]
  return {
    status: status,
    msg: msg,
    data: data,
  }
}

当我们写完云函数之后,我们需要把云函数上传到云开发的服务器上。怎么做呢?其实也很简单,我们只需要右键单击云函数的文件夹,选择“上传并部署:云端安装依赖(不上传node_modules)”

至此我们就完成了云函数的编写,接下来我们需要对云函数进行调用。

二 调用云函数

在小程序中,调用云函数是一件非常简单的事。我们只需要用过wx.cloud.callFunction即可。同时,小程序对云函数的调用是支持Promise风格的。什么是Promise?这对于js来说是个神器啊。我们有没有必要讲一下Promise,是有必要呢?还是有必要呢? 我们还是简单说一下Promise吧。简单的说,就是用来处理异步回调的神器。像获取网络数据就是一个典型的异步操作。对于我们来讲,只需要熟练使用.then()和.catch()就好。 现在,让我们回到云函数的回调上来。我们回想一下,什么时候会去调用云函数?1是界面初始化的时候,还有就是“换一批”和“刷新”图标被点击的时候。所以我们需要把调用云函数的代码写成一个函数:

onGetBest

这个函数我们写在methods块内。

/**
* 组件的方法列表
*/
methods: {
onGetBest:function(){
  wx.cloud.callFunction({
    name:"client_home_get_best"
  }).then(res=>{
    if (res.result.status == "success" &&res.result.data){
      this.setData({
        products:res.result.data
      })
    }
  }).catch(err=>{
    console.log(err)
  })
}
},

我们需要注意,在什么地方传入name的属性,也就是我们云函数的函数名“client_home_get_best”。 我们在then中接收云函数返回的数据。我们在云函数中返回的数据,都保存在res.result中。想想我们都返回了什么?status,msg和data。在这里,我们将以status是否为“success”和data是否存在为依据,来判断是否要更新“为你推荐”的数据。 调用云函数的函数就写完了,如果我有什么没讲清楚的,可以留言给我。 因为我们在界面初始化的时候,会调用一次云函数。所以我们要把onGetBest函数在attached中调用一次。接下来,我们要绑定点击事件。

三 绑定点击事件

在小程序的组件中,我们可以通过bindtap来绑定点击事件

bindtap=“onGetBest"

在这个界面中,我们要在两个组件上绑定点击事件,1是“换一批”文字,2是刷新图标,代码如下:

<view class="change" bindtap="onGetBest">换一批</view>
<van-icon color="gray" size="28rpx" name="replay" bindtap=“onGetBest"/>

是不是很简单? 我们再来做一个简单的处理是用户体验更好一些。是什么处理呢?就是当我们接受到数据后,我们再来显示“为你推荐”模块。怎么做到呢?我们可以通过wx:if来实现。怎么实现呢?通过判断绑定的数据products数组来判断,只有当products数组元素大于0时,才显示“为你推荐”模块。代码如下:

<view class="mid_menu" wx:if=“{{products.length>0}}">

云数据库初体验

在上一节,我们创建了第一个云函数,在这一节,我们来一起学习一下云数据库的使用。当我们学会了小程序界面的绘制,逻辑的编码,云函数的编写,云数据库的使用,我们会变成什么?变成一个什么都会做的全栈工程师,由于我们什么都会做。所以我们什么都要做,于是时间就不够啦,就要开始996,然后007,这是福报,马爸爸说的。 开个玩笑啦,我们先成为全栈工程师,然后目标是成为一个10x程序猿。随着能力的提高,升职加薪是必然的。小程序的流行势不可挡,它还没有停止进化,当我们一个人就可以快速的完成一个小程序的开发时,我们就可以依靠个人力量去做一些产品,万一这个产品火爆了呢?没准就实现财务自由了。这是一个很美好的梦想对不对?马爸爸也说过,人总是要有梦想的,万一实现了呢?如果马爸爸没说过,那就算作我说的。 好了,废话不多说,今天我们一起来学习以下三块内容:

❝1 创建集合 2 添加记录 3 云函数读取云数据库 ❞

一 创建集合

集合的概念,顾名思义,就是同类数据的集合。例如我们有个产品的集合里面放的都是产品的数据。我们的“为你推荐”模块就是从产品集合里面随机读取4条数据。 我们先来看看在开发者工具中如何创建集合。首先,点击“云开发”

然后点击“数据库”,并通过点击“+”号,创建集合。

在弹出的窗口中输入集合的名称,这里我们输入products:

点击“确定”,我们就能在左侧看到我们创建的集合了。

二 添加记录

接下里我们来添加记录,先点击我们的集合“products”,再点击“添加记录按钮”。

在弹出窗口,我们可以通过加号按钮添加该条记录的属性及值。

我们以添加产品名为例。字段名输入“name”,类型选择string,值输入“陨石拿铁”。

对于我们来讲,一条产品的记录光有name是不够的。一共有以下这几个字段:

name:产品名
nPrice:折后价格
oPrice:原始价格
thum:产品缩略图
image:产品大图
categoryId:产品分类id

其中image和categoryId暂时用不着,但我们预留着。 除了手动一条一条的添加记录之外,我们还可以批量导入数据。在我们点击集合名称“products”之后,我们选择“导入”按钮

在打开的窗口中点击“选择文件”,

找到我们的json文件(该文件我会在源代码中提供): 完成导入后我们就能看到我们导入的数据了:

我们来简单分析一下导入的数据。也就是我们的products.json文件。它虽然是以json结尾,但是又和我们平时接触的json不太一样。那我们就来做一个对比。普通的json文件如下

[
  {name:”拿铁”},
  {name:”陨石拿铁”}
]

我们可以看到中括号清晰的表示这是一个数组,数组内的每条记录之间还有逗号“,”相隔。 而云数据库中的集合用的是jsonline格式如下:

{name:”拿铁”}
{name:”陨石拿铁”}

数据外面没有中括号,记录之间也没有逗号“,”相隔。接下来,我们就要进入编码环节了。

三 云函数读取云数据库

接下来,我们要改造之前的云函数,将里面写死的数据,改成随机从数据库中读取。 我们打开“cloudfunctions/client_home_get_best/index.js”文件。在第四行添加两行代码:

const db = cloud.database()
const products = db.collection("products")

这两行代码什么意思呢?第一行,是用一个常量db表示我们对数据库的引用。接着再声明一个常量product表示我们对创建的集合“products”的引用。这样,我们就能通过products对产品数据进行操作了。 接下来,我们要实现的是,随机读取4条记录。

const data = await products
    .aggregate()
    .sample({
      size: 4
    })
    .end()

我们一行一行的解释,第一行,我们要注意到一个关键字“await”,这表示我们的数据读取是同步的,为什么要这么做呢?因为数据库的操作默认是异步的。如果我们不改成同步的,那么我们在获取数据之前,云函数就直接返回结果了,那我们就什么数据都拿不到了。所以,关键字await是必须的。 第二行 aggregate(),这表示我们要对集合进行聚合操作。 聚合操作能对记录进行一些复杂的处理,例如随机挑选数据。它通常end()做结束。 而第三行sample就是我们这次的关键了,它接收的参数size就表示是随机取出记录的数量。data是我们拿到的数据,但是data里面的list才是我们所要的,所以返回的时候要这么写:

return {
    ……
    data: data.list,
  }

最后来看看完整的代码:

// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()
const products = db.collection("products")
// 云函数入口函数
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()
const status = "success"
const msg = ""
const data = await products
    .aggregate()
    .sample({
size: 4
    })
    .end()
console.log(data)
return {
status: status,
msg: msg,
data: data.list,
  }
}

当我们写完index.js的代码,记得要将云函数的代码上传到云服务器上。怎么做呢?如下:

完整代码我放在了github上,地址是:https://github.com/gogoswift/luckin[1]

Reference

[1]

https://github.com/gogoswift/luckin:https://github.com/gogoswift/luckin

本文分享自微信公众号 - 图雀社区(tuture-dev),作者:曾伟@喵先森

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-06-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Taro 小程序开发大型实战(八):尝鲜 LeanCloud Serverless 云服务

    在上两篇文章中,我们讲解了使用微信小程序云作为我们的小程序后台,然后我们跑通了我们的注册登录、创建帖子、获取帖子列表、获取帖子详情的全栈流程,如果只想了解微信小...

    一只图雀
  • [译] 为新的Facebook.com重建我们的技术栈

    当我们考虑如何构建一个新的网络应用—一个为现代浏览器设计的、具有用户对Facebook(我们已知的)所有期望的功能,我们现有的技术栈无法支持我们所需要的类似于桌...

    一只图雀
  • 从零到部署:用 Vue 和 Express 实现迷你全栈电商应用(二)

    我们在平时所用到的一些网站、App,它们会将我们的数据进行保存,当我们关闭这些网站或者 App 后,下次打开还能看到我们之前的一些文字、视频记录。在迷你全栈电商...

    一只图雀
  • 基础渲染系列(二十)——视差(基础篇完结)

    这是有关渲染的系列教程的第20部分。上一部分介绍了GPU实例化。在这一部分中,我们将添加到目前为止尚不支持的标准着色器的最后一部分,即视差贴图。

    放牛的星星
  • CCAI 2017 | 日本理化学研究所杉山将:弱监督机器学习的研究进展

    日本理化学研究所先进智能研究中心主任杉山将 记者 | JayZhang 7 月 22 - 23 日,在中国科学技术协会、中国科学院的指导下,由中国人工智能学会、...

    AI科技大本营
  • Taro 小程序开发大型实战(八):尝鲜 LeanCloud Serverless 云服务

    在上两篇文章中,我们讲解了使用微信小程序云作为我们的小程序后台,然后我们跑通了我们的注册登录、创建帖子、获取帖子列表、获取帖子详情的全栈流程,如果只想了解微信小...

    一只图雀
  • CCAI 2017 | 日本理化学研究所先进智能研究中心主任杉山将:弱监督机器学习的研究进展

    用户1737318
  • Python函数之形参与实参

    各位小伙伴,大家晚上好 今天我们来一起探讨一下函数的另外一个重要概念 “形参”(xing2,can1)与“实参”(shi2,can1) 很多朋友可能第一次听到这...

    企鹅号小编
  • 第5章 Kotlin语言基础

    5.1 基础语法 5.1.1 包(package): package打包与import导包 5.1.2 变量 5.1.3 表达式 5.1.4 代码块 ...

    一个会写诗的程序员
  • SpringMVC常用配置

    按:最近公众号文章主要是整理一些老文章,主要是个人CSDN上的博客,也会穿插一些新的技术点。 ---- 关于Spring、SpringMVC我们前面几篇博客都介...

    江南一点雨

扫码关注云+社区

领取腾讯云代金券