- 云开发能力基础讲解
在上一节,我们大致体验了一下云开发:开通了云开发服务,相当于在云端拥有了一个 Nodejs 的环境,我们可以把云函数部署到云端。通过云开发的能力进行调用云函数、上传图片、操作数据库以及使用小程序的一些开放接口,下面来进一步了解和使用云开发能力,并加强对云端测试、本地调试以及本地 Console 日志打印,云端日志打印的理解。 用编程来写项目,就像是在做一系列精密而复杂的实验,你不能总是劳烦他人帮你解决问题,而是要掌握调试、测试、日志打印等手段来检查每一步操作是否正确,你需要学会查看报错信息,如果不正确问题在哪、出了什么问题,你才能有针对性的去搜索,有针对性的去咨询他人。 本地调试与云端测试 为了能够让大家更加清楚的了解:完整操作一个云函数的流程以及本地调试与云端测试的重要性,我们以长方形的边长(a、b)求周长、面积这个简单的数学公式为例。 第一步:新建云函数 首先我们右键点击云函数根目录(也就是 cloudfunctions 文件夹),选择新建 Nodejs 云函数,函数名为长方形的英文 rectangle,然后打开 index.js,修改 return 里的内容为如下: exports.main = async (event, context) => { const wxContext = cloud.getWXContext() return { circum:(event.width+event.height)*2, area:event.width*event.height } } circum 是周长,周长=(宽度 width+高度 height)✖️2;area 是面积,面积=宽度 width✖️ 高度 height,只要我们之后把长方形的参数宽度 width 和高度 height 传递进来(之后我们会来讲怎么传),即可获得长方形的周长和面积。 建好云函数之后,我们右键点击云函数目录,也就是 rectangle 文件夹,选择在终端中打开,使用 npm install 来安装依赖。 npm install 第二步:本地调试云函数是否正确 对于一个复杂的云函数,我们最好是先在本地测试一下云函数是否正确,然后再部署上传到云端。那如何本地测试呢?右键点击云函数目录,也就是 rectangle 文件夹,选择本地调试(这种方式进入本地调试会默认开启 rectangle 的本地调试),修改以下代码: { "key": "value" } 我们给参数宽度 width 和高度 height 赋值(注意传递的是 JSON 格式,最后一个参数结尾不能有逗号,),比如赋值为 3 和 6: { "width": 3, "height":7 } 然后点击调用,如果显示函数执行成功(注意仍然是在调试的 console 标签),并得到周长 circum 和面积 area 的结果分别为 20、21,那证明云函数没有写错,这时候我们就可以部署并上传到云端了。 第三步:云端测试云函数是否正确 打开云开发控制台的云函数标签页,找到 rectangle 云函数,点击云端测试,同样我们给参数赋值,将以下代码进行修改: { "key1": "test value 1", "key2": "test value 2" } 比如给宽度 width 赋值为 4,高度 height 赋值为 7,即代码修改为: { "width": 4, "height": 7 } 然后点击运行测试,(会等一段时间),再来查看测试的结果,如果返回结果如下,则表示在云端的云函数可以正常调用: {"circum":22,"area":28} 在云端测试的调用结果也是可以在云开发控制台云函数的日志里查看到的。 在第一节我们要触发云函数,需要在小程序页面里写一个组件(比如button)并绑定事件处理函数,然后再在事件处理函数(或在页面的生命周期函数)里使用wx.cloud.callFunction()调用云函数,通过这种方式来触发云函数,会比较麻烦,而本地调试和云端测试则可以直接触发云函数查看结果,大大提升了调试的便利度。 云函数的调用采用事件触发模型,小程序端的调用、本地调试和云端测试都会触发云函数的调用事件,其中本地调试调用的不是云端的云函数,而是小程序本地的云函数。 小任务:rectangle云函数需要传入两个参数才能返回值,有些云函数,比如前面的login云函数不需要传入参数,你知道应该怎么进行本地调试和云端测试吗?在本地调试的请求方式有手动触发和模拟器触发,开启模拟器触发,点击第一节“点击获取openid”的按钮试试看(注意这时调用的是本地的云函数,修改一下login云函数不上传试试看); 小程序端与服务端 小程序端与云端的初始化 小程序默认可以创建两个环境,这两个环境都有云函数配置、数据库、云存储且独立隔离,开发上会存在两个环境切换的情况(一个用于生产环境,一个用于测试环境),而区别这两个环境的就是它们的环境 ID,小程序端与云端的初始化时要注意。 在前面我们介绍过小程序的初始化是在 app.js 文件里使用 wx.cloud.init 来初始化,如下: wx.cloud.init({ env: 'my-env-id', //可以填写生产环境或者测试环境的环境ID traceUser: true, }) 这里的 env 只会决定小程序端 API 调用的云环境(如云函数、云存储、数据库,毕竟有两个环境里都有),并不会决定云函数中的 API 调用的环境。在开发者工具的控制台,也会打印默认环境: 当前代码初始化的默认环境为:你的默认环境 ID 当前代码初始化的默认环境为:你的默认环境 ID 云函数中的 API 调用的环境也可以使用初始化来设置。 cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV, }) cloud.DYNAMIC_CURRENT_ENV 设置 API 默认环境等于当前所在环境。建议所有的云函数都使用以上方式来初始化,也就是配置 env 的值为 cloud.DYNAMIC_CURRENT_ENV 或使用你的环境 ID,不要为空。 关于 wx-server-sdk 每一个云函数都会用到 wx-server-sdk 这个 Node 包,而要使用这个包都需要有 Nodejs 环境,小程序端的本地需要我们自己下载 Nodejs(前面已下载),而云端则自带 Nodejs 环境。那这个 wx-server-sdk 到底什么呢?我们可以打开它的 npm 包地址: npm 包地址:wx-server-sdk 包地址 在 Dependencies 标签页可以看到 wx-server-sdk 依赖 tcb-admin-node、protobufjs、tslib 这三个包,而其中 tcb-admin-node 是核心,学有余力的童鞋可以看一下它的技术文档。 技术文档:tcb-admin-node 的 Github 地址 async 与 await 在 wx-server-sdk 中不再兼容 success、fail、complete 回调,只会返回 Promise。在云函数中也经常会需要处理一些异步操作,在异步操作完成后再返回结果给到调用方,我们可以通过在云函数中返回一个 Promise 的方法来实现。Promise 表示异步操作返回的结果。在新建的云函数里会看到下面这样的一个语句(有 async): exports.main = async (event, context) => { } async 表示函数里有异步操作,async 函数的返回值是一个 Promise 对象。在后面还会遇到 await,表示紧跟在它后面的表达式需要等待结果;以及 promise 对象的 then()方法(有点类似于 success 回调函数),和 catch()方法(有点类似于 fail 回调函数),这些我们以后会经常遇到,先理解不了也没有关系,大家在书写时推荐云函数使用上面的写法就对了。 云函数的注意事项 在云函数部署并上传到云端之后,更新里面的文件比如index.js、config.json,建议右键点击更新好的文件(不是云函数目录)选择云函数增量上传:更新文件,不建议通过上传并部署所有文件的方式,否则在几分钟内会出现云函数调用失败的情况; 删除一个云函数之后,不建议再新建一个同名的云函数并上传部署,否则在十多分钟内会出现云函数调用失败的情况,建议换一个云函数名,比如login换成user,在小程序端使用 wx.cloud.callFunction({name: ''})调用云函数时把name的值换成user就可以了 调用云函数时,我们还可以在开发者工具调试面板的NetWork标签查看调用云函数的情况。 获取用户信息和登录 在生命周期章节,我们大致介绍了一下如何使用 wx.getUserInfo API 和通过组件的 open-type=”getUserInfo” 来获取用户的信息(如头像、昵称),下面我们就来详细介绍云开发的免鉴权登录与用户信息的结合。 使用open-type=”getUserInfo” 来获取用户信息的作用和 wx.getUserInfo API基本效果是一样的,区别在于wx.getUserInfo 这种方式最好是在用户允许获取公开信息(也就是res.authSetting[‘scope.userInfo’]的值为true)之后再调用,如果用户拒绝了授权就不会再有弹窗(除非用户删掉了你的小程序再使用),调用就会失败,而使用组件的方式是用户主动点击,用户即使拒绝了,再点击仍会弹出授权弹窗。所以推荐先使用组件来获取用户授权,然后再来使用wx.getUserInfo来获取用户信息。 通过 button 获取用户信息 使用开发者工具新建一个 login 页面,然后在 login.wxml 里输入以下代码,我们通过组件的方式来获取用户的信息: <button open-type="getUserInfo" bindgetuserinfo="getUserInfomation">点击获取用户信息</button> <image src="{{avatarUrl}}"></image> <view>{{city}}</view> <view>{{nickName}}</view> 在 login.js 的 data 里初始化 avatarUrl、nickName 以及 city,没有获取到用户信息时,用一张默认图片代替,昵称显示用户未登录,city 显示为未知: data: { avatarUrl: '/images/user-unlogin.png', nickName:"用户未登陆", city:"未知", }, 然后在 login.js 文件里输入以下代码,在事件处理函数 getUserInfomation 我们可以打印 event 对象,open-type=”getUserInfo”的组件的 event 对象的 detail 里就有 userInfo: getUserInfomation: function (event) { console.log('getUserInfomation打印的事件对象', event) let { avatarUrl, city, nickName}= event.detail.userInfo this.setData({ avatarUrl,city, nickName }) }, 将获取的 avatarUrl,city,nickName 通过 this.setData()赋值给 data。编译之后点击点击获取用户信息按钮,首先会弹出授权弹窗,当用户确认之后,就会显示用户的信息。 获取用户高清头像 我们发现获取到的头像不是很清晰,这是因为默认的头像大小为 132132(UserInfo 用户头像说明),如果把 avatarUrl 链接后面的 132 修改为 0 就能获取到 640640 大小的头像了: getUserInfomation: function (event) { let { avatarUrl, city, nickName}= event.detail.userInfo avatarUrl = avatarUrl.split("/") avatarUrl[avatarUrl.length - 1] = 0; avatarUrl = avatarUrl.join('/'); this.setData({ avatarUrl,city, nickName }) }, 页面加载时就显示用户信息 在获得了用户授权和用户信息的情况下,刷新页面或进行页面跳转,用户的个人信息还是不会显示,这是因为 getUserInfomation 事件处理函数点击组件时才触发,我们需要在页面加载时也能触发获取用户信息才行。 我们可以在 login.js 的 onLoad 生命周期函数里输入以下代码,当用户授权之后来调用 wx.getUserInfo() API: wx.getSetting({ success: res => { if (res.authSetting['scope.userInfo']) { wx.getUserInfo({ success: res => { let { avatarUrl, city, nickName } =res.userInfo this.setData({ avatarUrl, city, nickName }) } }) } } }); 这样当我们加载页面时,用户的信息就能显示出来了,不过这里的头像是从 API 里重新取的,也会不清晰。我们当然可以像之前一样把头像的链接替换一下,但是如果每个页面都这么写就会很麻烦,解决的方法有 2 种,一种是把高清头像存储到缓存里,还有一种是把代码封装成一个组件(大家可以自己研究如何自定义组件了)。 openid、用户信息与登录 尽管我们已经获取到了用户的头像、昵称等信息,但是这不能称之为真正意义的登录,只有获取到了用户身份的唯一 ID 也就是 openid,我们才能把用户行为比如点赞、评论、发布文章、收藏等与用户挂钩,用户这些行为都与数据库有关,而能够确定点赞、评论、文章、收藏这些数据与用户关系的就是 openid,也就是说只要获取到了 openid 就意味着用户已经登录,而获取用户信息(如头像、昵称)不过是一个附加服务,这两个是可以完全独立的。没有 openid,我们也无法把用户信息给存储到数据库,也就没法让用户自定义用户信息。无论是用户行为,还是用户的信息,openid 都是一个重要的桥梁。 通过前面的login云函数,我们就已经可以获取到用户的openid。无需维护复杂的鉴权机制,即可获取天然可信任的用户登录态(openid),是云开发的一个重要优势。无论是云存储还是云数据库,openid都扮演着一个重要的角色。 小程序端上传图片到云存储 要把图片上传到云存储,会使用到 wx.cloud.uploadFile,这个 API 是小程序端的 API,它是把本地资源也就是临时文件里的文件上传到云存储里。在前面《图片、缓存与文件》章节里我们已经了解到如何把图片上传到小程序的临时文件,而要把临时文件上传到云存储,则需要调用 wx.cloud.uploadFile API。 技术文档:wx.cloud.uploadFile 在 wx.cloud.uploadFile 技术文档里,可以看到要调用 API,需要获取图片的 filePath,在小程序里为临时文件的路径,也就是要把上传到小程序的临时文件路径赋值给它;还有一个 cloudPath,这个为文件的云存储路径,这个是我们可以任意设置的。 使用开发者工具在 login.wxml 里添加以下代码,代码和前面章节基本一致,大家也可以回顾一下以前的内容: <button bindtap="chooseImg">选择图片</button> <image mode="widthFix" src="{{imgurl}}"></image> 然后在 login.js 的 data 里初始化 imgurl,这里 imgurl 是一个字符串, data: { imgurl: "", }, 然后在 login.js 里添加事件处理函数 chooseImg,我们再来回顾一下临时文件的知识: chooseImg: function () { wx.chooseImage({ count: 1, sizeType: ['compressed'], sourceType: ['album', 'camera'], success: function (res) { console.log(res) console.log(res.tempFilePaths) } }) }, 编译后,上传一张图片,在控制台里我们可以看到 res.tempFilePaths 是一个数组格式,而 wx.cloud.uploadFile 的 filePath 是一个字符串,所以我们在上传时,可以把第一张图片的路径(字符串)赋值给 filePath: const filePath = res.tempFilePaths[0] 文件名与后缀的处理 我们知道一个文件由文件名称和文件后缀构成,比如 tcb.jpg 和 cloudbase.png,jpeg 说明图片的格式是 JPG 格式,而 png 说明图片是 PNG 格式,文件名称相同且格式相同就是出现覆盖,如果我们随意更改了文件的后缀,大多数文件就会打不开。所以要把 cloudPath 云存储的路径需要我们把文件名和后缀给处理好。 当我们把图片上传到小程序的临时文件后,我们可以查看一下临时路径是什么样子的: http://tmp/wx7124afdb64d578f5.o6zAJs291xB-a5G1FlXwylqTqNQ4.esN9ygu5Hmyfccd41d052e20322e6f3469de87f662a0.png 临时路径的文件名就不是原来的文件名,会变成一段长字符,但文件的格式还是原来的文件格式(后缀)。那 cloudPath 要输入文件的路径,就需要填写文件名和文件格式,这个要怎么处理呢? 在上一节的 QuickStart 小程序里,文件上传到云存储的处理方式如下: const cloudPath = 'my-image' + filePath.match(/\.[^.]+?$/)[0] 也就是它把上传的所有图片都命名为 my-image,而文件的后缀还是原来的文件后缀(也就是文件格式不变)。这里的 filePath.match(/.[^.]+?$/)[0]是字符串的正则处理,后面我们会来详细了解。我们先可以在开发者工具的控制台输入以下代码了解一下它的功能: const filepath="http://tmp/wx7124afdb64d578f5.o6zAJs291xB-a5G1FlXwylqTqNQ4.esN9ygu5Hmyfccd41d052e20322e6f3469de87f662a0.png" filepath.match(/\.[^.]+?$/)[0] 打印可以得到临时文件的后缀,这里为.png。这种把所有文件都命名为 my-image 的做法,会导致当文件的后缀相同时文件会被覆盖,如果不希望文件被覆盖,我们需要给文件命不同的名字,我们可以这样处理: const cloudPath = `${Date.now()}-${Math.floor(Math.random(0, 1) * 1000)}` + filePath.match(/\.[^.]+?$/)[0] 给文件名加上时间戳和一个随机数,时间戳是以毫秒计算,而随机数是以 1000 内的正整数,除非 1 秒钟(1 秒=1000 毫秒)上传几十万张照片,不然文件名是不会重复的。 结合上面的内容,我们可以把 wx.chooseImage()的 success 回调函数如下处理: success: function (res) { const filePath = res.tempFilePaths[0] const cloudPath = `${Date.now()}-${Math.floor(Math.random(0, 1) * 1000)}` + filePath.match(/\.[^.]+?$/)[0] wx.cloud.uploadFile({ cloudPath, filePath, success: res => { console.log('上传成功后获得的res:', res) }, }) } 编译之后,我们再次上传一张图片就会打印上传成功之后的 res 对象,里面包含图片在云存储里的 fileID,注意它的文件名和文件后缀,以及我们可以在云开发控制台的存储里找到你上传的图片,也就是说我们上传图片到云存储是无法直接获取到图片的下载地址的。 云存储的二级目录 在存储里我们都是把所有的图片放在根目录下,没有二级目录,那我们能不能建一个二级目录呢?当然是可以的,我们可以在 cloudPath 的前面加一个文件路径就可以了,比如: const cloudPath = `cloudbase/${Date.now()}-${Math.floor(Math.random(0, 1) * 1000)}` + filePath.match(/\.[^.]+?$/)[0] 渲染云存储图片到组件 在上一节组件支持部分了解到,我们是可以把 fileID 直接在小程序的某些组件里渲染出来的。综合以上内容 chooseImg 事件处理函数最终为以下代码(注意 this.setData 的 this 指向,这里为了方便把 success 回调都写成了箭头函数): chooseImg: function () { wx.chooseImage({ count: 1, sizeType: ['compressed'], sourceType: ['album', 'camera'], success: res=> { const filePath = res.tempFilePaths[0] const cloudPath = `cloudbase/${Date.now()}-${Math.floor(Math.random(0, 1) * 1000)}` + filePath.match(/\.[^.]+?$/)[0] wx.cloud.uploadFile({ cloudPath, filePath, success: res => { console.log('上传成功后获得的res:', res) const imgurl=res.fileID this.setData({ imgurl }) }, }) } }) }, 在云开发控制台的存储里,我们可以看到每张图片的详细信息都有上传者 Open ID,无论你是使用开发者工具在模拟器的小程序里上传还是预览在手机的小程序里上传,只要你用的是同一个微信账号,这个上传者openid都是一致的,云存储会自动记录上传者的openid。 小任务:结合《图片、缓存与文件》章节里的wx.chooseMessageFile()的知识,将客户端会话(微信聊天窗口)里的视频、音频、PDF、Excel 等也上传到云存储里。 云函数上传图片到云存储 云开发不仅在小程序端可以上传文件到云存储,还可以通过云函数也就是云端上传图片到云存储(这里会涉及到一点 Nodejs 的知识)。 技术文档:uploadFile 注意云函数上传图片的 API 属于服务端 API,与 wx.cloud.uploadFile 是小程序端 API 不同。 使用开发者工具右键点击云函数根目录也就是 cloudfunctions 文件夹,选择新建 Node.js 云函数,云函数的名称命名为 uploadimg,右键点击 uploadimg 文件夹,选择硬盘打开,然后拷贝一张图片如 demo.jpg 进去,文件结构如下: uploadimg云函数目录 ├── index.js ├── package.json ├── demo.jpg 然后打开 index.js,输入以下代码: const cloud = require('wx-server-sdk') const fs = require('fs') const path = require('path') cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV, }) exports.main = async (event, context) => { const fileStream = fs.createReadStream(path.join(__dirname, 'demo.jpg')) return await cloud.uploadFile({ cloudPath: 'tcbdemo.jpg', fileContent: fileStream, }) } 然后右键点击 uploadimg 文件夹,选择在终端中打开,输入 npm install 安装依赖,再点击 uploadimg 文件夹,选择上传并部署所有文件(这时图片也一并上传到了云端)。 由于云端测试无法获取用户登陆态信息,所以我们不能在云端测试里把图片上传到云存储,需要在小程序端调用,使用开发者工具在 login.wxml 输入以下代码,也就是新建一个绑定 uploadimg 事件处理函数的 button 用于触发: <button bindtap="uploadimg">云函数上传图片</button> 然后在 login.js 里输入以下代码,在事件处理函数 uploadimg 里调用 uploadimg 云函数,并返回调用之后的 res 对象: uploadimg() { wx.cloud.callFunction({ name: 'uploadimg', success: res => { console.log(res) } }) }, 编译之后,点击云函数上传图片按钮,就可以调用 uploadimg 云函数,从而调用 uploadFile API 将服务端/云端的图片上传到云存储里面啦,可以打开云开发控制台的云存储查看是否有 tcbdemo.jpg 这张图片。 注意,通过这种方式上传到云存储的图片,是没有上传者 Open ID的,在云存储里查看这张图片的详细信息,就可以了解到。 调用数据库 数据库的导入 在调用数据库之前,我们需要先有一个比较贴近实际的数据库案例,为此把前面章节用到的知乎日报数据整理出了一个数据库文件。云开发数据库支持用文件的方式导入已有的数据(这里推荐大家使用 json)。 数据库下载:知乎日报文章数据 右键点击链接,将 data.json 存储到电脑。为了方便大家阅读与编辑 data.json 文件的内容,推荐大家使用 Visual Studio Code 编辑器。 代码编辑器:Visual Studio Code 编辑器的汉化与插件:可能你安装的VS Code的界面是英文的,可以参照VSCode设置中文显示,将VS Code汉化。 使用 VS Code 编辑器打开 data.json,发现数据的内容与写法我们都比较熟悉,知识各个记录对象之间是使用回车 \n 分隔,而不是逗号,这一点需要大家注意。 打开云开发控制台,在数据库里新建一个集合 zhihu_daily,导入该 json 文件,导入时会有冲突模式选择,看下面的介绍,推荐大家使用 upsert: Insert:总是插入新记录Upsert:如果记录存在则更新,否则插入新记录导入后,发现数据库自动给每一条数据(记录)都加了唯一的标识_id。 小程序端调用数据库 在小程序端调用数据库的方式很简单,我们可以把下面的代码写到一个事件处理函数里,然后点击组件触发事件处理函数来调用;也可以直接写到页面的生命周期函数里面;还可以把它写到 app.js 小程序的生命周期函数里面。 使用开发者工具,将下面的代码写到 login.js 的 onLoad 函数里面,我们 先使用 wx.cloud.database()获取数据库的引用(相当于连接数据库);再使用 db.collection()获取集合的引用;再通过 Collection.get 来获取集合里的记录.const db = wx.cloud.database() db.collection('zhihu_daily') .get() .then(res => { console.log(res.data) }) .catch(err => { console.error(err) }) 编译之后,就能在控制台看到调用的 20 条数据库记录了(如果没有指定 limit,则默认最多取 20 条记录)。 云函数调用数据库 使用云函数也可以调用数据库,使用开发者工具右键点击云函数根目录也就是 cloudfunctions 文件夹,选择新建 Node.js 云函数,云函数的名称命名为 zhihu_daily,然后打开 index.js,输入以下代码: const cloud = require('wx-server-sdk') cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) const db = cloud.database() exports.main = async (event, context) => { return await db.collection('zhihu_daily') .get() } 然后右键点击 index.js,选择云函数增量上传:更新文件,我们既可以使用云函数的本地调试(要本地调试需要使用 npm install 安装 wx-server-sdk 依赖),也可以使用云端测试来了解云函数调用数据库的情况。 openid 与数据库 在云开发控制台的数据库标签里,打开上一节内容里的 counters 集合,在这个集合里我们可以看到每条记录除了有_id 字段以外,还有一个_openid 字段用来标志每条记录的创建者(也就是小程序的用户)。但是在我们使用管理端(控制台和云函数)中创建的数据比如我们之前导入的 zhihu_daily,就不会有 _openid 字段,因为这些记录属于管理员(不是用户)创建的记录。 我们可以自定义 _id(也就是给数据添加一个_id 字段并填入任意值),但不可自定义和修改 _openid 。 _openid 是在文档创建时由系统根据小程序用户默认创建的,可以用来标识和定位文档。和云存储一样,数据库的记录也和 openid 有着紧密的联系。
2021-09-10 - 云开发快速入门
如果你想免费、快速的开发出一个完整的项目,用小程序的云开发可能是最好的选择。小程序的云开发所用到的主要是前端开发的知识。 注册微信小程序 小程序的注册非常方便,打开小程序注册页面,按照要求填入个人的信息,验证邮箱和手机号,扫描二维码绑定你的微信号即可,3 分钟左右的时间即可搞定。 注册页面:小程序注册页面 https://mp.weixin.qq.com/ 注册小程序时不能使用注册过微信公众号、微信开放平台的邮箱哦,也就是需要你使用一个其他邮箱才行。 当我们注册成功后,就可以自动登入到小程序的后台管理页面啦,如果你不小心关掉了后台页面,也可以点击小程序后台管理登录页进行登录。 后台管理页:小程序后台管理登录页 https://mp.weixin.qq.com/ 小程序和微信公众号的登录页都是同一个页面,他们会根据你的不同的注册邮箱来进行跳转。 进入到小程序的后台管理页后,点击左侧菜单的开发进入设置页,然后再点击开发设置,在开发者 ID 里就可以看到 AppID(小程序 ID),这个待会我们有用。 注意小程序的ID(AppID)不是你注册的邮箱和用户名,你需要到后台查看才行哦~ 必备工具与云开发文档 大家可以根据自己的电脑操作系统来下载相应的版本,注意要选择稳定版 Stable Build 的开发者工具。 开发者工具:小程序开发者工具下载地址 和学习任何编程一样,官方技术文档都是最值得阅读的参考资料。技术文档大家先只需要花五分钟左右的时间了解大致的结构即可,先按照我们的教学步骤学完之后再来看也不迟哦。 技术文档:云开发官方文档 由于小程序的云开发在不断新增功能,更新非常频繁,所以要确保自己的开发者工具是最新的哦(不然会报很多奇奇怪怪的错误),比如你之前下载过要先同步到最新才行~ 体验云开发模板小程序 安装完开发者工具之后,我们使用微信扫码登录开发者工具,然后使用开发者工具新建一个小程序的项目: 项目名称:这个可以根据自己的需要任意填写;目录:大家可以先在电脑上新建一个空文件夹,然后选择它;AppID:就是之前我们找到的 AppID(小程序 ID)(也可以下拉选择 AppID)开发模式为小程序(默认),后端服务选择小程序·云开发点击新建确认之后就能在开发者工具的模拟器里看到云开发 QuickStart 小程序,在编辑器里看到这个小程序的源代码。 接下来,我们点击开发者工具的工具栏里的预览图标,就会弹出一个二维码,使用微信扫描这个二维码就能在手机里看到这个小程序啦。 如果你没有使用微信登录开发者工具,以及你的微信不是该小程序的开发者是没法预览的哦。 在手机里(或模拟器)操作这个小程序,把小程序里的每个按键都点一遍,看看会有什么反应。我们会发现很多地方都会显示“调用失败”等,这非常正常,我们接下来会通过一系列的操作让小程序不报错。 开通云开发服务 点击微信开发者工具的“云开发”图标,在弹出框里点击“开通”,同意协议后,会弹出创建环境的对话框。这时会要求你输入环境名称和环境 ID,以及当前云开发的基础环境配额(基础配额免费,而且足够你使用哦)。 建议你环境名称可以使用 xly、环境ID自动生成即可,当你的云开发环境出现问题的时候,你可以提供你的环境ID,云开发团队会有专人为你解答。 按照对话框提示的要求填写完之后,点击创建,会初始化环境,环境初始化成功后会自动弹出云开发控制台,这样我们的云开发服务就开通啦。大家可以花两分钟左右的时间熟悉一下云开发控制台的界面。 找到云开发的环境 ID 点击云开发控制台窗口里的设置图标,在环境变量的标签页找到环境名称和环境 ID。 当云开发服务开通后,我们可以在小程序源代码 cloudfunctions 文件夹名看到你的环境名称。如果在 cloudfunctions 文件夹名显示的不是环境名称,而是“未指定环境”,可以鼠标右键该文件夹,选择“更多设置”,然后再点击“设置”小图标,选择环境并确定。 指定小程序的云开发环境 在开发者工具中打开源代码文件夹 miniprogram 里的 app.js,找到如下代码: wx.cloud.init({ // 此处请填入环境 ID, 环境 ID 可打开云控制台查看 env: 'my-env-id', traceUser: true, }) 在 env: 'my-env-id'处改成你的环境 ID,如 env: 'xly-snoop' 下载 Nodejs NodeJS 是在服务端运行 JavaScript 的运行环境,云开发所使用的服务端环境就是 NodeJS。npm 是 Node 包管理器,通过 npm,我们可以非常方便的安装云开发所需要的依赖包。 npm是前端开发必不可少的包(模块)管理器,它的主要功能就是来管理包package,包括安装、卸载、更新、查看、搜索、发布等,其他编程语言也有类似的包管理器,比如Python的pip,PHP的composer、Java的maven。我们可以把包管理器看成是windows的软件管理中心或手机的应用中心,只是它们用的是可视化界面,包管理器用的是命令行Command Line。 下载地址:Nodejs 下载地址 大家可以根据电脑的操作系统下载相应的 NodeJS 安装包并安装(安装时不要修改安装目录,啥也别管直接 next 安装即可)。打开电脑终端(Windows 电脑为 cmd 命令提示符,Mac 电脑为终端 Terminal),然后逐行输入并按 Enter 执行下面的代码: node --version npm --version 如果显示为 v10.15.0 以及 6.11.3(可能你的版本号会有所不同),表示你的 Nodejs 环境已经安装成功。 学编程要仔细,一个字母,一个单词,一个标点符号都不要出错哦。注意输上面的命令时node、npm的后面有一个空格,而且是两个短横杠–。 部署并上传云函数 部署并上传云函数 cloudfuntions 文件夹图标里有朵小云,表示这就是云函数根目录。展开 cloudfunctions,我们可以看到里面有 login、openapi、callback、echo 文件夹,这些就是云函数目录。而 miniprogram 文件夹则放置的是小程序的页面文件。 cloudfunctions里放的是云函数,miniprogram放的是小程序的页面,这并不是一成不变的,也就是说你也可以修改这些文件夹的名称,这取决于项目配置文件project.config.json里的如下配置项: "miniprogramRoot": "miniprogram/", "cloudfunctionRoot": "cloudfunctions/", 但是你最好是让放小程序页面的文件夹以及放云函数的文件夹处于平级关系且都在项目的根目录下,便于管理。 使用鼠标右键其中的一个云函数目录比如 login,在右键菜单中选择在终端中打开,打开后在终端中输入以下代码并按 Enter 回车执行: npm install 如果显示“npm不是内部或外部命令”,你需要关闭微信开发者工具启动的终端,而是重新打开一个终端窗口,并在里面输入 cd /D 你的云函数目录进入云函数目录,比如 cd /D C:\download\tcb-project\cloudfunctions\login进入login的云函数目录,然后再来执行npm install命令。 这时候会下载云函数的依赖模块,下载完成后,再右键 login 云函数目录,点击“创建并部署:所有文件”,这时会把本地的云函数上传到云端,上传成功后在 login 云函数目录图标会变成一朵小云。 在开发者工具的工具栏上点击“云开发”图标会打开云开发控制台,在云开发控制台点击云函数图标,就能在云函数列表里看到我们上传好的“login”云函数啦。 上传所有云函数 接下来我们按照这样的流程把其他所有云函数(如 openapi)都部署都上传,也就是要执行和上面相同的步骤,总结如下: 右键云函数目录,选择在终端中打开,输入 npm install命令下载依赖文件; 然后再右键云函数目录,点击“创建并部署:所有文件” 在云开发控制台–云函数–云函数列表查看云函数是否部署成功。 login、openapi、echo、callback这些云函数在后面都会用到的哦,一定要确定自己部署上传成功,不然后面会报错的哦。 npm 包管理器与依赖模块 为什么要在云函数目录执行 npm install,而不是其他地方?这是因为 npm install 会下载云函数目录下的配置文件 package.json 里的 dependencies,它表示的是当前云函数需要依赖的模块。package.json 在哪里,就在哪里执行 npm install,没有 package.json,没有 dependencies,就没法下载啊。 执行 npm install 命令下载的依赖模块会放在 node_modules 文件夹里,大家可以在执行了 npm install 命令之后,在电脑里打开查看一下 node_modules 文件夹里下载了哪些模块。 既然 npm install 是下载模块,那它是从哪里下载的呢?就以 wx-server-sdk 为例,我们可以在以下链接看到 wx-server-sdk 的情况: https://www.npmjs.com/package/wx-server-sdk 为什么 package.json 里依赖的是一个模块 wx-server-sdk,但是 node_modules 文件夹里却下载了那么多模块?这是因为 wx-server-sdk 也依赖三个包 tcb-admin-node、protobuf、jstslib,而这三个包又会依赖其他包,子子孙孙的,于是就有了很多模块。 node_modules 文件夹这么大(几十 M~几百 M 都可能),会不会影响小程序的大小?小程序的大小只与 miniprogram 文件夹有关,当你把云函数都部署上传到服务器之后,你把整个 cloudfuntions 文件夹删掉都没有关系。相同的依赖(比如都依赖 wx-server-sdk)一旦部署到云函数之后,你可以选择不上传 node_modules 时,因为已经上传过了。 获取 openid 与云函数 login 当我们把云函数 login 部署上传成功后,就可以在模拟器以及手机(需要重新点击预览图标并扫描二维码)里点击获取 openid 了。 点击获取 openid openid 是小程序用户的唯一标识,也就是每一个小程序用户都有一个唯一的 openid。点击“点击获取 openid”,在用户管理指引页面如果显示“用户 id 获取成功”以及一串字母+数字,那么表示你 login 云函数部署并上传成功啦。如果获取 openid 失败,你则需要解决 login 云函数的部署上传,才能进行下面的步骤哦。 调用云函数的解读 小程序的首页是”pages/index/index”,我们可以从 app.json 的配置项或者模拟器左下角的页面路径可以看出来。在 index.wxml 里有这段代码: <button class="userinfo-nickname" bindtap="onGetOpenid">点击获取 openid</button> 也就是当点击“点击获取 openid”按钮时,会触发 bindtap 绑定的事件处理函数 onGetOpenid,在 index.js 里可以看到 onGetOpenid 事件处理函数(在 index.js 里找到事件处理函数 onGetOpenid 对比理解)调用了 wx.cloud.callFunction()接口(打开技术文档对比理解) 技术文档:调用云函数 wx.cloud.callFunction 调用云函数的方法很简单,只需要填写云函数的名称 name(这里为 login),以及需要传递的参数(这里并没有上传参数),就可以进行调用。在 success 回调函数里添加以下代码打印 res 对象: console.log('调用login云函数返回的res',res) 添加完成之后记得保存代码哦,文件修改没有保存会在标签页有一个小的绿点。可以使用快捷键(同时按)Ctrl和S来保存(Mac电脑为Command和S)。 编译之后,再点击“点击获取 openid”按钮,就能看到完整的 res 对象,res 对象有三个参数: requestID:云函数执行 ID,可用于在云开发控制台查找日志,打开云开发控制台–云函数–日志,可以在这里根据云函数函数名以及 requestID 来筛选查看云函数的调用日志(含返回结果);result:云函数返回的结果,login 云函数返回的结果里包含 appid、event 对象,我们可以通过 res.result.appid 以及 res.result.event 访问它们;errMsg:显示云函数是否调用成功事件处理函数 onGetOpenid 调用云函数成功之后,干了三件事情: 使用 console.log 打印 openid,可以在点击按钮触发云函数在控制台看到该打印结果;把获取到的 appid 赋值给 app.js 文件里的 globalData 全局对象;跳转到 userConsole 页面;而 userConsole 页面就只是从 globalData 里将 openid 取出来通过 setData 渲染到页面。 小任务:你明白为啥wx.cloud.callFunction()是小程序端的API了么?思考一下为啥云开发会有小程序端的API和服务端API的区别?能理解多少是多少,不清楚也没有关系,后面会有更多内容助你理解。 云函数 login 解读 为什么调用云函数 login 返回的 res 的 result 对象里会包含 event 对象、appid、userInfo 这些结果?这就取决于云函数是怎么写的了。使用开发者工具打开 login 云函数(在 cloudfuntions 文件夹里)的 index.js。 exports.main = (event, context) => {} 这是一个箭头函数的写法,其中 event 和 context 是参数。我们将两个打印日志修改为以下代码,相当于备注一下到底打印到哪里去了: console.log('服务端打印的event',event) console.log('服务端打印的context',context) 保存之后,右键点击 index.js 文件,选择云函数增量上传:(更新文件),更新 login 云函数,我们再来点击“点击获取 openid”按钮,打印的结果在哪里呢?在云开发控制台的云函数日志里面(注意不是开发者工具的控制台)。打开云开发控制台–云函数–日志,按函数名筛选,选择 login 云函数,可以看到云函数被调用的日志记录,我们可以在日志里发现: event 对象包含程序用户的 openid 和小程序的 appid,而 openid 就相当于用户的身份证,我们可以根据 openid 获取到用户的昵称、头像等信息(后面会说明);而 context 对象则是云函数的调用信息和运行状态。在返回结果里我们可以看到 return 返回的数据小任务:比较一下云开发控制台的云函数日志打印的结果和开发者工具控制台打印的结果,深入了解 event 对象、context 对象、result 对象与返回结果,这是云函数的比较重要的知识点。云函数的打印日志会显示在云开发控制台的日志里面,这一点非常重要,要多加利用。只要是打印日志,无论是显示在开发者工具控制台还是显示在云开发控制台的就没有不重要的。 getWXContext() getWXContext()API 是云开发服务端的工具类 API,会返回小程序用户的 openid、小程序 appid、小程序用户的 unionid 等。说这么多不如直接打印,在下面添加一行打印信息: const wxContext = cloud.getWXContext() console.log('getWXContext返回的结果',wxContext) 保存之后,右键点击 index.js 文件,选择云函数增量上传:(更新文件),更新 login 云函数,我们再来点击“点击获取 openid”按钮,然后去云开发控制台的云函数日志里看到底返回了什么结果。 技术文档:getWXContext() 对照技术文档来理解返回的结果。 注意小程序用户 unionid只有在开发者帐号下存在同主体的公众号或移动应用,并且该用户已经授权登录过该公众号或移动应用才能获得。 return return 语句是终止函数的执行,并返回一个指定的值给函数调用者。这里返回了 4 个值,而前面我们就调用过 login 云函数,就是函数的调用者,所以我们打印的事件处理函数 onGetOpenid 的回调函数的 res 对象正是这个 return 返回的结果。那既然如此,我们在 return 多加一些内容看看,比如我们之前的一些数据结构案例,将 return 函数改为如下代码: let lesson = "云开发技术训练营"; let enname = "CloudBase Camp"; let x = 3, y = 4, z = 5.001, a = -3, b = -4, c = -5; let now = new Date(); return { movie: { name: "霸王别姬", img: "https://img3.doubanio.com/view/photo/s_ratio_poster/public/p1910813120.webp", desc: "风华绝代。" }, movielist:["肖申克的救赎", "霸王别姬", "这个杀手不太冷", "阿甘正传", "美丽人生"], charat: lesson.charAt(4), concat: enname.concat(lesson), uppercase: enname.toUpperCase(), abs: Math.abs(b), pow: Math.pow(x, y), sign: Math.sign(a), now: now.toString(), fullyear: now.getFullYear(), date: now.getDate(), day: now.getDay(), hours: now.getHours(), minutes: now.getMinutes(), seconds: now.getSeconds(), time: now.getTime(), event, openid: wxContext.OPENID, appid: wxContext.APPID, unionid: wxContext.UNIONID, } 保存之后,右键点击 index.js 文件,选择云函数增量上传:(更新文件),更新 login 云函数,我们再来点击“点击获取 openid”按钮,然后去云开发控制台的云函数日志里看到底返回了什么结果。 这里我们多次反复提及更新了index.js文件之后就要选择云函数增量上传:(更新文件),更新login云函数,希望大家平时的时候注意,这也是小程序云开发服务端和小程序端一个非常大的区别。 新建云函数 鼠标右键 cloudfunctions 云函数根目录,在弹出的窗口选择新建 Node.js 云函数,比如输入 sum,按 Enter 确认后,微信开发者工具会在本地(你的电脑)创建出 sum 云函数目录,同时也会在线上环境中创建出对应的云函数(也就是自动部署好了,可以到云开发控制台云函数列表里看到) 打开 sum 云函数目录下的 index.js,添加 sum:event.a+event.b,到 return 函数里(把多余的内容可以删掉了),然后记得选择云函数增量上传:(更新文件),更新 sum 云函数。 return { sum:event.a+event.b, } 这个 a 和 b 是变量,但是和前面不一样的是,在服务端我们并没有声明 a 和 b 啊,这是因为我们可以在小程序端声明变量。 点击开发者工具模拟器的“快速新建云函数”,会跳转到 addFunction 页面,打开 addFunction.wxml,我们看到测试云函数绑定的是 testFunction 事件处理函数。 <view class="list-item" bindtap="testFunction"> <text>测试云函数</text> </view> 我们去看 addFunction.js 里的 testFunction,看变量 a 和 b 这两个小程序端的变量是怎么和服务端的变量关联起来的,而又是如何把结果渲染到页面的。testFunction 调用云函数 sum 同样是通过 wx.cloud.callFunction,不同的是在 data 里有 a 和 b: data: { a: 1, b: 2 }, data 里填写的是传递给云函数的参数,也就是先把小程序端的参数传递给云函数,然后云函数处理之后再返回 res 对象,我们可以在 success 回调函数里打印 res 对象: console.log("sum云函数返回的对象",res) 编译之后,我们再点击测试云函数,在控制台就能看到打印的结果,res.result.sum 就是 3。直接把 res.result.sum 通过 setData 赋值到 result 就能渲染出数字,那这个 res.result 是什么?JSON.stringify()又是什么? result: JSON.stringify(res.result) 我们可以打印一下 res.result,以及 JSON.stringify(res.result) console.log("res.result是啥", res.result) console.log("JSON.stringify(res.result)是啥", JSON.stringify(res.result)) res.result 是对象,而 JSON.stringify(res.result)是 json 格式, JSON.stringify() 方法是将一个 JavaScript 值(对象或者数组)转换为一个 JSON 字符串,因为对象如果直接渲染到页面是会显示 [object Object]的。 小任务:将小程序的参数传递给云端,有没有一点wx.request的感觉?相当于我们通过云函数写好了一个数据API,然后在小程序端调用。新建一个云函数,把各种数学运算都部署到云端,然后通过传递参数,调用这些算法,并将结果渲染到页面。 体验上传图片 上传图片到云存储 使用模拟器以及手机端点击云开发 QuickStart 小程序的上传图片按钮,选择一张图片并打开,如果在文件存储指引页面显示上传成功和文件的路径以及图片的缩略图,说明你的图片就上传到云开发服务器里啦。 点击云开发控制台的存储图标,就可以进入到存储管理页查看到你之前上传的图片啦,点击该图片名称可以看到这张图片的一些信息,如:文件大小、格式、上传者的 OpenID 以及存储位置、下载地址和 File ID。复制下载地址链接,在浏览器就能查看到这张图片啦。 值得注意的是由于QuickStart小程序将“上传图片”这个按钮上传的所有图片都命名为my-image,所以上传同一格式的图片就会被覆盖掉,也就是无论你上传多少张相同格式的图片,只会在后台里看到最后更新的那张图片。以后我们会教大家怎么修改代码,让图片不会被覆盖。 组件支持 我们可以把下载地址作为图床来使用的,也就是你可以把图片的下载地址放到其他网页图片是可以显示的。云存储的图片还有一个 FileID(既云文件 ID,以 cloud://开头)则只能用于小程序的特定场景,也只有部分组件的部分属性支持,把链接粘贴到浏览器也是打不开的。 技术文档:组件支持 比如我们在 index 页面的 index.wxml 里输入以下代码,在 image 组件的 src 属性里输入你的云存储图片的 FileID,它是可以显示出来的。 <image src="你的图片的FileID"></image> 但是如果你退出登录开发者工具,图片就不会显示,而且还会报错,所以不要把图片的 FileID 当做图床用,FileID 另有它用。 体验云调用之服务端调用 重新点击开发者工具的预览图标,然后用手机扫描二维码,在手机端点击云开发 QuickStart 的云调用里的服务端调用,就可以发送模板消息和获取小程序码。 点击获取小程序码,如果显示调用失败,说明你的 openapi 云函数没有部署成功,需要你先部署成功才行哦。调用成功,就能获取到你的小程序码啦,这个小程序码也会保存到云开发的存储里。 发送模板消息,只能在手机微信里预览测试哦,使用微信开发者工具是发送不了模板消息,而且控制台还会报错 点击发送模板消息,你的微信就会收到一则服务通知,该通知是由你的小程序发出的购买成功通知。这就是微信的模板消息啦,很多微信公众号、小程序都会有这样的功能,使用小程序云开发,我们也可以轻松定制自己的服务通知(后面会教大家如何定制)。 体验前端操作数据库 点击微信开发者工具的云开发图标,打开云开发控制台,点击数据库图标进入到数据库管理页,点击集合名称右侧的+号图标,就可以创建一个数据集合了,这里我们只需要添加一个 counters 的集合(不需添加数据)即可。 在开发者工具的编辑器里展开 miniprogram 文件夹,打开 pages 文件下 databaseGuide 里的 databaseGuide.js 文件,在这里找到 onAdd: function (){}、 onQuery: function (){}、 onCounterInc: function (){}、 onCounterDec: function (){}、 onRemove: function (){}分别选中绿色的代码块,然后同时按快捷键 Ctrl 和/(Mac 电脑的快捷键为 Command 和/),就可以批量取消代码的注释。 //是前端编程语言JavaScript的单行注释,位于 // 这一行的代码都不会执行,我们使用快捷键就是批量取消这些代码的注释,让整段代码生效。之所以显示为绿色,是微信开发者工具为了让我们看得更清晰而做的语法高亮。 前端操作数据库的页面逻辑 以上的函数是在小程序的前端页面来操作数据库,点击开发者工具模拟器云开发 QuickStart 里的前端操作数据库, 在第1步(数据库指引有标注),我们会获取到用户的openid,也就是说你没有获取到openid是没法通过小程序的前端来操作数据库的哦 第2步,需要我们在云开发控制台里的数据库管理页创建一个counters的集合(不需添加数据); 第3步,点击按钮页面的按钮“新增记录”(按钮就在这个页面的第4条与第5条之间,看起来不是那么明显),这时会调用 onAdd方法,往counters集合新增一个记录(之前手动添加有木有很辛苦?),我们可以去云开发控制台的数据库管理页查看一下counters集合是不是有了一条记录;大家可以多点击几下新增记录按钮,然后去云开发控制台看数据库又有什么变化。也就是小程序前端页面通过 onAdd方法,在数据库新增了记录。 第4步,点击按钮查询记录,这时调用的是 onQuery方法就能在小程序里获取到第3步我们存储到数据库里的数据啦 第5步,点击计数器按钮+号和-号,可以更新count的值,点击+号按钮会调用 onCounterInc方法,而点击-号 onCounterDec方法,比如我们点击加号到7,再去数据库管理页查看最新的一条记录(也就是最后一条),它的count由原来的1更新到了7(先点刷新按钮),我们再点击-号按钮到5,再来数据库管理页查看有什么变化变化(先点刷新按钮) 第6步,点击删除记录按钮,会调用 onRemove方法,这时会删掉数据库里最新的记录(也就是第5步里的那一条记录)。 通过实战我们了解到,databaseGuide.js 文件里的 onAdd、 onQuery、 onCounterInc、 onCounterDec、 onRemove 可以实现小程序的前端页面来操作数据库。 这些函数大家可以结合 databaseGuide.js 文件和云开发技术文档关于数据库的内容来理解。(关于前端是如何操作数据库的,我们之后还会深入讲解,这里只需要了解大致的逻辑即可) 在前面JavaScript的章节里我们了解到数据以及数据的存储是非常重要的,而有了数据库,用函数生成的数据能够比缓存存储的更加持久,而且在上面我们实现了对数据进行增(添加)、删(删除)、改(修改、更新)、查(查询并渲染到页面),不仅如此,缓存的容量也比较有限,最多不过10M,而数据库可以存几百G以上,可见它的重要性。 开始一个新的云开发项目 基于云开发 QuickStart 模板小程序 云开发 QuickStart 模板小程序有很多多余的页面,这个我们只需要把 miniprogram 文件夹下的 pages、images、components、style 文件夹里的文件清空,以及 app.json 的 pages 配置项里的页面删除,把 app.wxss 里的样式代码都删掉就是一个全新的开始啦。这是方法之一,也可以使用下面的方法(推荐学习时使用下面的方法)。 基于没有使用云开发的项目改造 当然我们也可以把前面章节没有使用云开发的项目改造成使用云服务,首先在小程序的根目录下新建一个文件夹,比如 cloudfunctions,然后在 project.config.json 添加云函数文件夹的路径配置即可, "cloudfunctionRoot": "cloudfunctions/", 然后新建一个 miniprogram 文件夹,把小程序除了 project.config.json 以外的其他文件,比如 pages、utils、images、app.js、app.json 等文件都放到 miniprogram 文件夹里,再在 project.config.json 添加 miniprogramRoot 配置: "cloudfunctionRoot": "cloudfunctions/", "miniprogramRoot":"miniprogram/", 值得一提的是,云函数部署上传成功,我们就可以一直调用,只要你的小程序的appid以及环境ID没有变,你创建再多的小程序项目,都可以直接调用部署好的云函数,比如前面的login、echo、callback、sum等云函数。也就是说云函数一旦部署成功,它就一直在云端服务器里,哪怕你把小程序本地的云函数都删掉也没有关系。 当新建了并配置了云函数根目录为 cloudfunctions 文件夹之后,云函数根目录里并没有云函数,我们可以右键点击云函数根目录 cloudfunctions 文件夹选择同步云函数列表,可以把所有云端的云函数列表都列举出来(这只是列举了列表),而要修改云函数里面的内容,我们可以右键点击其中的一个云函数目录选择下载云函数即可。 除此之外,我们需要小程序的 app.js 的生命周期函数 onLaunch 里使用 wx.cloud.init()来初始化云开发能力: onLaunch: function () { if (!wx.cloud) { console.error('请使用 2.2.3 或以上的基础库以使用云能力') } else { wx.cloud.init({ env: '你的环境ID', traceUser: true, }) } }, 云开发能力全局只需要初始化一次即可,这里的 traceUser 属性设置为 true,会将用户访问记录到用户管理中,在云开发控制台的运营分析—用户访问里可以看到访问记录。 基础库与 wx.cloud 在小程序端初始化云开发能力的代码里,涉及到 wx.cloud 以及基础库版本的知识。关于 wx.cloud,我们可以和之前在控制台了解 wx 对象一样,直接在开发者工具的控制台里输入: wx.cloud 来了解对象有哪些属性与方法。我们可以看到有如下方法: CloudID: ƒ () //用于云调用获取开放数据 callFunction: ƒ () //调用云函数 database: ƒ () //获取数据库的引用 deleteFile: ƒ () //从云存储空间删除文件 downloadFile: ƒ () //从云存储空间下载文件 getTempFileURL: ƒ () //用云文件 ID 换取真实链接 init: ƒ () //初始化云开发能力 uploadFile: ƒ () //上传文件至云存储空间 而关于基础库,有三个地方需要注意它的存在,平时开发的时候需要留意开发者工具的project.config.json里有这样一个属性libVersion,这个也可以在开发者工具工具栏右上角的详情里的本地设置里的调试基础库,建议切换到最新,切换后libVersion的值也会修改到切换的版本; 官方文档基础库的更新日志,小程序更新非常频繁,而更新的核心就是基础库:所以基础库更新日志要经常留意每个API,技术文档都会标明它的基础库支持的最低版本,而小程序·云开发 SDK是2.2.3以上的基础库才开始支持的。
2021-09-10 - 小程序日历组件推荐
小程序日历组件推荐 这几天在做民宿小程序,遇到一个需求就是 用户选择日期,来下单,由于民宿每天的价格都是变化的,所以要在日历上显示价格,找了很久,终于找到了 vant https://youzan.github.io/vant-weapp/#/calendar 1 [图片] 2 [图片] 3 具体使用方法如下所示 [图片] 4 具体小程序界面截图如下所示: 5 [图片] 6 7 现在说起来都是风轻云淡,但是找的过程又盲目,有着急,开发中,也遇到各种问题,好在,回过头去,vant calendar就是我要找的日历组件 8
2020-06-07