1. 云开发简介
由于小程序本身存储数据的能力有限, 所以不可能将大量的数据保存在客户端, 而且将数据保存在本地既不安全, 也无法与其他小程序用户共享, 所以大多数小程序都需要一个服务端, 服务端可以用多种技术实现, 如 PHP,Node.JS,Python,ASP.NET,Java EE 等. 不管使用哪种技术实现服务端, 开发一款小程序都需要至少配备两个程序员, 一个是开发小程序的程序员, 一个是开发服务端的程序员. 而且这两个程序员之间还需要不断沟通, 以便确认共同遵循的接口.
开发一款小程序需要两名或更多的程序员参与, 一直困扰着很多小的创业公司, 因为多雇佣一个人, 就会增加很多成本. 所以基于这个痛点, 很多公司推出了云开发技术, 例如 Bmob 就是较早推出云开发的公司, 所谓云开发, 就是将服务端的功能都封装起来, 然后向客户端提供 API 访问这些封装的功能. 服务端的主要功能无外乎数据存储, 文件上传下载, 视频 / 音频流等功能. 这些功能大多开发都不困难, 但比较费时, 所以将其封装起来供客户端调用是一个非常好的主意.
腾讯最近推出了自己的云开发系统, 不过这个云开发系统目前只能用于小程序, 而且只提供了如下 3 种.
云数据库
云存储
云函数
云数据库是指在服务端提供的数据库服务, 小程序云提供的数据库属于文档数据库, 文档数据库有别于关系型数据库. 传统的关系型数据库中可以保存若干个表, 每一个表由若干条记录组成. 但文档数据库保存的是 JSON 格式的数据, 每一个 JSON 文档相当于关系型数据库中的一个表. 也就是说, 文档数据库保存的是 JSON 文档的集合. 非常流行的 MongoDB 就是典型的文档数据库. 云数据库个组成部分对应的关系如下表所示.
关系数据库 | 文档数据库 |
---|---|
数据库(database) | 数据库(database) |
表(table) | 集合(collection) |
行(row) | 记录(record/doc) |
列(column) | 字段(field) |
云存储为小程序提供了远程上传和下载文件的能力. 下载可以提供权限管理, 小程序可以通过相应的 API 实现文件的上传和下载功能.
云函数就是一段可以运行在服务端的代码, 之所以要将部分代码在服务端运行, 主要有如下两个原因:
部署多个用户共享, 且容易维护的代码
获取敏感信息, 如 appid,openid 等.
2. 搭建云开发环境
现在让我们来开发第一个与云的小程序, 首先应该下载最新版的微信开发者工具, 然后在小程序后台获取 AppID. 使用云开发功能, 必须使用真实的 AppID, 不能使用测试用的 AppID.
启动微信开发者工具, 新创建一个小程序工程. 在创建小程序工程的过程中, 需要输入 AppID 和项目名称, 然后在最下面的目标列表中选择 "建立云开发快速启动模板" 选项, 如下图所示.
创建完支持云开发的小程序工程后, 工程目录结构和 IDE 主界面如下图所示. 当前工程默认带了一些例子 (模板中的例子) 来帮助理解和开发基于云的小程序.
如果第一次使用这个 AppID 开发基于云的小程序, 应该单击界面上方的 "云开发" 按钮, 会显示如下图所示的页面.
这是一个开通云服务的页面, 单击 "开通" 按钮, 就会开通用于云开发的服务. 在开通的过程中会出现如下图所示的确认对话框, 单击 "确定" 按钮进入下一个设置页面.
这个页面是 "新建环境" 页面, 如下图所示. 需要输入 "环境名称", 一个任意的字符串. 在下面列出了基础版的配置. 如数据库存储空空间, 云函数数量等. 如果想要更多的资源, 那以后肯定是要收费的. 天下没有免费的午餐. 不过这个配置做实验和用户量不是非常大的小程序还是够用的.
单击 "确定" 按钮, 就会创建一个环境, 然后会进入如下图所示的云开发控制台. 在这个控制台中可以管理用户, 云数据库, 云存储, 云函数以及统计分析. 并且会显示相关的信息, 如今日 API 调用
如果想创建新环境, 可以将鼠标放在右侧当前环境 minicloud 上, 会弹出如下图所示的菜单, 单击 "创建新环境" 菜单项就会创建一个新的环境, 目前每个小程序账号课免费创建两个新环境.
3. 部署 login 云函数
模板会默认创建一个 login 云函数, 用于返回 openid(标识当前微信登录用户的 ID), 所以在开发基于云的小程序之前, 首先要先部署 login 云函数.
选中 login 云函数, 在右键菜单中单击 "上传并部署" 菜单项进行部署, 如下图所示.
成功部署 login 云函数后, 回到小程序的主页面, 单击 "点击获取 openid" 按钮, 如下图所示, 会通过 login 云函数获取 openid.
成功通过 login 云函数获取 openid 后, 会显示如下图的页面. 现在就可以使用云 API 来开发小程序了.
4. 开始实战
现在我们来开发第一个基于云的小程序, 这个小程序非常简单, 就是在一个集合中插入一条数据, 也就是一个 JSON 格式的文本.
一个集合就相当于一个表. 选择环境后, 小程序就会默认有一个数据库, 所以就不需要单独创建数据库了, 只需要在该数据库中创建若干个集合 (表) 即可.
首先打开云开发控制台, 切换到 "数据库" 页面, 单后单击左上角的 "添加集合", 会弹出如下图所示的 "添加集合" 对话框, 输入集合的名字, 然后单击 "确定" 按钮添加集合.
创建一个新集合后的效果如下图所示. 可以通过单击右侧的 "添加记录" 导入 JSON 或 CSV 文件, 每个文件最大 50MB. 不过本节并不会通过云开发控制台导入, 而是使用代码来插入文档.
由于获得 openid 后, 会跳到 userConsole 页面, 所以我们在这个页面的 onLoad 函数中向 test 集合插入一个 JSON 文档.
在小程序开发工具中定位到 userConsole.JS 文件, 并找到 onLoad 函数, 如下图所示.
在 onLoad 函数中会从全局变量 (globalData) 中获取 openid. 操作集合首先要通过 init 函数初始化环境, init 函数的语法格式如下:
wx.cloud.init({env:envname})
其中 envname 是字符串类型的值, 表示要使用的环境名, 在前面已经创建了一个名为 minicloud 的环境了, 所以本例的 envname 的值是'minicloud'.
然后使用下面的代码获取数据库和集合对象.
- const db = wx.cloud.database()
- const test = db.collection('test')
其中 test 是前面建立的集合名.
最后使用 add 方法插入 JSON 格式的数据, 完整的代码如下:
- wx.cloud.init({
- env:'minicloud'
- })
- const db = wx.cloud.database()
- const test = db.collection('test')
- test.add({
- // data 字段表示需新增的 JSON 数据
- data: {
- name: "Bill",
- age:30
- },
- success: function (res) {
- // 输出成功插入后的 id 以及其他信息
- console.log(res)
- }
- })
现在重新运行程序, 获取 openid 后, 就会在小程序开发者工具的 Console 中看到如下图的信息.
回到云开发控制台, 会看到 test 集合多了如下图所示的数据. 这表明 JSON 文档已经插入成功.
现在来改进前面编写的基于云的小程序. 这个小程序尽管可以向云数据库中插入数据, 不过代码与模板代码混在了一起, 在真正的小程序项目中, 不可能让用户先单击按钮获得 openid, 再进行下面的操作, 所以现在重新编写基于云的小程序. 主要包括如下功能.
从文本输入组件输入姓名和年龄, 单击 "插入数据" 按钮向云数据库插入包含信命和年龄的数据.
从文本输入组件输入记录 ID, 单击 "查询数据" 按钮, 从云数据库中查询相关的数据, 并将查询到的数据中的姓名和年龄显示在页面上.
小程序主界面如下图所示.
为了在我们自己页面上实现这些功能, 首先在小程序工程中创建一个 main 目录, 并创建如下图所示的文件.
接下来修改 App.JSON 文件, 将 main 页面变成首页(第一个显示的页面), 也就是将 "pages/main/main" 放在 pages 数组的第一个元素的位置, 修改后的 App.JSON 文件的内容如下:
- {
- "cloud": true,
- "pages": [
- "pages/main/main",
- "pages/userConsole/userConsole",
- "pages/storageConsole/storageConsole",
- "pages/databaseGuide/databaseGuide",
- "pages/addFunction/addFunction",
- "pages/deployFunctions/deployFunctions",
- "pages/chooseLib/chooseLib"
- ],
- "window": {
- "backgroundColor": "#F6F6F6",
- "backgroundTextStyle": "light",
- "navigationBarBackgroundColor": "#F6F6F6",
- "navigationBarTitleText": "云开发 QuickStart",
- "navigationBarTextStyle": "black"
- }
- }
现在重新运行小程序, 会看到 main 页面已经成为了小程序的首页. 由于本例的页面需要用到一些组件, 所以需要现在 main.wxml 文件中输入下面的代码完成
main 页面的布局.
- <view>
- <input style='margin-top: 40rpx;' placeholder="请输入姓名" value="{{name}}"
- bindinput="bindKeyInputName" />
- <input style='margin-top: 40rpx;' placeholder="请输入年龄" value="{{age}}"
- bindinput="bindKeyInputAge" />
- <button style='margin-top: 40rpx;' bindtap='insertData'>
- 插入数据
- </button>
- <input style='margin-top: 40rpx;' placeholder="请输入记录 ID" value="{{recordId}}"
- bindinput="bindKeyInputId" />
- <button style='margin-top: 40rpx;' bindtap='queryData'>
- 查询数据
- </button>
- <text style='margin-top: 40rpx;'>
姓名:{{nameResult}}
- </text>
- <text style='margin-top: 80rpx;'>
年龄:{{ageResult}}
</text>
</view>
在 main.wxml 文件中, 包含 3 个 < input > 组件和 2 个 text 组件, 这 5 个组件分别与 age,name,recordId,nameResult 和 ageResult 五个变量绑定, 修改和获取这 5 个组件的值也只需要考虑这 5 个变量即可.
在小程序中调用云 API 之前, 必须要获取小程序的 openid, 这个 openid 表示当前小程序的用户 ID. 由于进入小程序必须要通过微信, 所以小程序使用与微信相同的用户验证体系, 因此, 小程序就不需要单独登录了, 而 openid 就是小程序是否登录的凭证.
获取 openid 的代码已经包含在模板中了, 只需要找到 index.JS 文件, 并搜索 onGetOpenid 函数, 会看到如下的代码.
- onGetOpenid: function() {
- // 调用云函数
- wx.cloud.callFunction({
- name: 'login',
- data: {
- },
- success: res => {
- console.log('[云函数] [login] user openid:', res.result.openid)
- App.globalData.openid = res.result.openid
- wx.navigateTo({
- url: '../userConsole/userConsole',
- })
- },
- fail: err => {
- console.error('[云函数] [login] 调用失败', err)
- wx.navigateTo({
- url: '../deployFunctions/deployFunctions',
- })
- }
- })
- }
上面的代码用于调用名为 login 的云函数获取小程序的 openid. 通常只需要将 onGetOpenid 函数中的代码直接复制到 main.JS 文件中的 onLoad 函数即可.
向云数据库插入数据的代码前面已经学过, 一会大家可以看本例完整的代码. 从云数据库中查询数据可以使用下面的代码.
- db.collection(集合名).doc(记录 ID).get(
- {
- // 查询到数据后触发, res 参数值包含的查询到 数据
- success:function(res) {
- },
- // 未查询到数据触发
- fail:function(res) {
- }
- })
main.JS 中完整的实现代码如下:
- // miniprogram/pages/main/main.JS
- const App = getApp()
- Page({
- /**
- * 页面的初始数据
- */
- db:undefined,
- test:undefined,
- data: {
- name:'',
- age:'',
- recordId:'',
- nameResult:'',
- ageResult:''
- },
- /**
- * 生命周期函数 -- 监听页面加载
- */
- onLoad: function (options) {
- var that = this
- // 调用 login 云函数获取 openid
- wx.cloud.callFunction({
- name: 'login',
- data: {},
- success: res => {
- console.log('[云函数] [login] user openid:', res.result.openid)
- App.globalData.openid = res.result.openid
- wx.cloud.init({ env: 'minicloud' })
- that.db = wx.cloud.database()
- that.test = that.db.collection('test')
- },
- fail: err => {
- console.error('[云函数] [login] 调用失败', err)
- wx.navigateTo({
- url: '../deployFunctions/deployFunctions',
- })
- }
- })
- },
- // 单击 "插入数据" 按钮调用该函数
- insertData:function() {
- var that = this
- try
- {
- // 将年龄转换为整数类型值
- var age = parseInt(that.data.age)
- // 如果输入的年龄不是数字, 会显示错误对话框, 并退出该函数
- if(isNaN(age))
- {
- // 显示错误对话框
- wx.showModal({
- title: '错误',
- content: '请输入正确的年龄',
- showCancel: false
- })
- return
- }
- // 向 test 数据集添加记录
- this.test.add({
- // data 字段表示需新增的 JSON 数据
- data: {
- name: that.data.name,
- age: age
- },
- // 数据插入成功, 调用该函数
- success: function (res) {
- console.log(res)
- wx.showModal({
- title: '成功',
- content: '成功插入记录',
- showCancel:false
- })
- that.setData({
- name:'',
- age:''
- })
- }
- })
- }
- catch(e)
- {
- wx.showModal({
- title: '错误',
- content: e.message,
- showCancel: false
- })
- }
- },
- // 单击 "查询数据" 按钮执行该函数
- queryData:function() {
- var that = this
- // 根据记录 ID 搜索数据集
- this.db.collection('test').doc(this.data.recordId).get({
- // 找到记录集调用
- success: function (res) {
- // 将查询结果显示在页面上
- that.setData({
- nameResult:res.data.name,
- ageResult:res.data.age
- })
- },
- // 未查到数据时调用
- fail:function(res) {
- wx.showModal({
- title: '错误',
- content: '没有找到记录',
- showCancel: false
- })
- }
- })
- },
- // 下面的函数用于当更新 input 组件中的值时同时更新对应变量的值
- bindKeyInputName: function (e) {
- this.setData({
- name: e.detail.value
- })
- },
- bindKeyInputAge:function(e) {
- this.setData({
- age: e.detail.value
- })
- },
- bindKeyInputId:function(e) {
- this.setData({
- recordId:e.detail.value
- })
- },
- })
现在重新运行小程序, 并添加一些数据, 看到云开发控制台中的 test 集合下多了几条记录, 如下图所示. 这表明已经将数据成功插入 test 集合.
现在回到小程序开发界面, 在 "查询按钮" 上方的文本输入框中输入一条记录的 ID, 单击 "查询数据" 按钮, 会看到按钮下方会显示如下图的查询结果, 如果未查询到结果, 会显示一个提示对话框.
来源: http://blog.51cto.com/androidguy/2308368