版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
第9章小程序云开发电子工业出版社现代的各类应用程序一般都需要网络环境支持才能运行:所谓网络环境,究其本质就是运行于前端设备的程序,比如,Web前端程序、APP前端程序、微信小程序等,都需要与处于后端的服务器系统程序进行信息交互才能完成特定的用户业务。也就是说,程序的业务数据及业务逻辑程序都是在服务端进行存储和处理的,而运行于前端设备的程序只是完成与用户的UI(UserInterface)交互而已。因此,在设计和开发信息业务系统时,需要设计和开发前端程序的同时,还需要设计和开发后处于后端的服务器系统程序。处于后端的服务器系统程序也需要计算机设备来运行:用户可以自行购买和部署所需的计算机设备,也可以从各个云平台提供商购买云端服务器设备。针对微信小程序,同时也考虑到微信小程序的“小”特性,微信提供了一种适合微信小程序的称为“云开发”的技术来满足微信小程序的后台服务器系统需求。目录9.1云开发入门9.2初始化云开发环境9.3云数据库9.4云存储9.5云函数9.6案例:在线竞选班长9.7练习:个人财务9.1云开发入门微信小程序“云开发”,简单来说就是:微信提供了一组API,通过这组API,微信小程序开发者可以将微信小程序的业务数据保存到“云数据库”中,同时也可以对保存在云数据库中的数据进行增删改查操作;再者,微信小程序开发者可以将微信本地文件存储到“云存储”中,之后可以像访问任何网络文件一样访问所保存的云文件,当然,用户可以根据需要随时删除所保存的云文件;其三,微信小程序开发者还可以将一些具有特定功能的函数发布成为“云函数”,然后,采用特定的方式来访问已经发布的的云函数。9.1.1云开发前必读用微信小程序云开发技术,由于要使用微信的计算机CPU资源、RAM资源、存储资源等资源,因此,使用微信云开发是需要付费的。简单来说,使用微信云开发,相当于用户拥有了一个自己的小型云平台,用户省去了购买或者租赁后端服务器的费用,但是,需要为使用的微信云开发相关资源支付费用。9.1.2开通云开发第一步,首先注册称为微信小程序开发者,并获得小程序AppID;第二步,新建一个微信小程序项目,在弹出的“创建小程序”界面的“AppID”一栏输入获得的小程序AppID,在“开发模式”一栏选择“小程序”,在“模板选择”中选择“不使用模板”,然后,点击“确定”即可创建一个可以开通云开发的普通小程序工程。特别提醒:在上面这个新建项目的操作中,一旦选择了“不使用模板”,在“后端服务”一栏,会自动选择“不使用云服务”选项,读者可能会对这个选项存在不解:既然所创建的项目已经“不适用云服务”了,那后续还能进行云开发吗?回答是“完全能”!读者也可能还有一个问题:既然微信开发者工具提供了很多开发模板,为什么不选用这些模板呢?回答是:如果在学习阶段选用了模板,会自动导入很多与学习无关的代码从而导致程序工程复杂,不便于学习,因此,建议不选用已有模板。完成了小程序工程的创建任务后,会显示所创建的小程序工程的首界面,例如,创建了名称为mini-ch09-01的小程序工程后,显示如图所示的界面。点击箭头所指向的“云开发”按钮,将显示开通云开发的界面,在开通云开发的界面中输入称为“环境”的名字。在下面的例子中,将以“teaching”为云开发环境的名字。然后点击“确定”后即可开通云开发,之后,将显示如图所示的云开发控制台界面。9.1.3云开发控制台使用基础进入云开发控制台后,首先显示云环境的概览数据。点击“数据库”按钮,可以对云数据库进行操作,如图所示。对于云数据库,需要首先理解如下几个关键概念:其一,一个云环境对应一个云数据库;其二,云数据库的一个集合对应关系数据库的一张表,一个集合本质上就是一个JSON数组;其三,集合中的一个对象对应关系数据库的一条记录,一条记录本质上就是一个JSON对象。点击“存储”按钮,可以对云存储进行操作。如图所示。所谓“云存储”,就是微信小程序可以将本地的文件存储到云端系统中,并可以像操作其他网络文件一样操作存储在云存储中的文件。点击“云函数”按钮,可以对云函数进行操作。如图9-5所示。所谓“云函数”,就是自定义的存储在云端的函数,这些云函数可以被小程序调用。云函数的独特之处在于:云函数可以完成一些在微信小程序客户端难以完成的功能,例如,删除云数据库中的多条记录等。9.1.4云开发入门举例对已经创建的小程序项目mini-ch09-01进行云开发。这个例子完成以下业务功能:(1)从云数据库goods集合中检索所有记录;(2)向云数据库goods集合中插入一条记录;(3)修改云数据库goods集合中的一条记录数据;(4)删除云数据库goods集合中的一条记录;(5)删除云数据库goods集合中的多条记录;(6)从微信小程序本地选择一个图像文件上传到云存储并将这个云文件显示在微信小程序界面中。在小程序工程目录下新建名称为cloudfunctions的目录,然后,在小程序工程的根目录下打开项目配置文件“project.config.json”,在其中添加语句:"cloudfunctionRoot":"cloudfunctions/",这条语句进行云函数配置:未来在程序中所设计开发的所有云函数将放置在小程序工程目录的cloudfunctions/下。右击cloudfunctions目录,并选择“当前环境”选项,最后在列出的选项中选择在开通云开发时所命名的云开发环境的名称,如图所示:由于这个例子中需要在云数据库中对数据进行增删改查操作,因此,还需要通过云开发控制台在云数据库中新建的一个名称为goods的云数据库集合。在编写云开发代码之前,需要初始化云开发环境,为此,修改小程序的app.js文件为如下内容:修改index.wxml文件,在界面上显示业务功能按钮。修改后的index.wxml文件内容如下://app.jsApp({onLaunch(){wx.cloud.init();//初始化云开发环境}})<!--index.wxml--><navigation-bartitle="Weixin"back="{{false}}"color="black"background="#FFF"></navigation-bar><buttonbindtap="list"style="width:100%;margin:2px;">检索所有数据</button><buttonbindtap="insert"style="width:100%;margin:2px;">插入一条数据</button><buttonbindtap="update"style="width:100%;margin:2px;">修改一条数据</button><buttonbindtap="delete"style="width:100%;margin:2px;">删除一条数据</button><buttonbindtap="ddelete"style="width:100%;margin:2px;">删除多条数据(价格小于3000)</button><buttonbindtap="cupload"style="width:100%;margin:2px;">选择图像文件上传到云端并显示</button><imagesrc="{{cimage}}"mode="widthFix"></image>修改index.js为如下代码://index.jsPage({db:{},
data:{cimage:''},
onReady(){this.db=wx.cloud.database();},
list(){this.db.collection('goods').get().then(res=>{res.data.forEach(r=>{console.log(r);});});},insert(){this.db.collection('goods').add({data:{//_id字段,数据库自动分配name:"电冰箱",price:2111},success:function(res){console.log(res);}});},
update(){this.db.collection('goods').doc('63ca5b13661b35d307256ebb0ec13718').update({data:{price:2000},success(res){console.log('修改数据成功!')},fail(res){console.log('Failed!');console.log(res);}});},
delete(){this.db.collection('goods').doc('63ca5b13661b35d307256ebb0ec13718').remove({success:function(res){console.log("成功删除了记录!")}});},
ddelete(){wx.cloud.callFunction({//云函数名称name:'mdelete',success(res){console.log(res.result)},fail(){console.error();}})},cupload(){letthat=this;wx.chooseMedia({count:1,mediaType:['image'],sourceType:['album','camera']}).then(res=>{console.log(res.tempFiles[0].tempFilePath);wx.cloud.uploadFile({cloudPath:'example.png',//上传至云端的路径filePath:res.tempFiles[0].tempFilePath,//小程序临时文件路径success:res=>{//返回文件IDconsole.log(res.fileID);that.setData({cimage:res.fileID});},fail:console.error});})}})为了在微信开发环境中新建一个云函数,在云函数根目录cloudfunctions上右击,在右键菜单中,选择“创建一个新的Node.js云函数”,将该云函数命名为mdelete,之后,开发者工具在本地创建出云函数目录和入口index.js文件,如图所示。在开发者工具本地创建了云函数的同时,会在线上环境中创建出对应的云函数,如图所示。打开cloudfunctions/mdelete/index.js文件(也就是打开mdelete云函数的js代码文件),修改其中的内容为如下代码://云函数入口文件constcloud=require('wx-server-sdk');cloud.init({env:cloud.DYNAMIC_CURRENT_ENV});//使用当前云环境constdb=cloud.database();const_=mand;//云函数入口函数exports.main=async(event,context)=>{try{returnawaitdb.collection('goods').where({price:_.lt(3000)}).remove()}catch(e){console.error(e)}}修改了mdelete云函数后,右击mdelete云函数,在弹出的菜单中选择“上传并部署:云端安装依赖(不上传nodemodules)“以同步修改后的云函数到云端。接着,定义了页面“选择图像文件上传到云端并显示”按钮的处理函数:cupload(){letthat=this;wx.chooseMedia({count:1,mediaType:['image'],sourceType:['album','camera']}).then(res=>{console.log(res.tempFiles[0].tempFilePath);wx.cloud.uploadFile({cloudPath:'example.png',//上传至云端的路径filePath:res.tempFiles[0].tempFilePath,//小程序临时文件路径success:res=>{//返回文件IDconsole.log(res.fileID);that.setData({cimage:res.fileID});},fail:console.error});})}现在运行这个程序。在程序主界面,点击“检索所有数据”按钮,将显示如图所示的界面:在微信客户端的控制台上列出了云数据库中的所有数据。在程序主界面,点击“插入一条记录”按钮,将在goods云数据库集合中插入一条新的记录。此时,打开云开发界面,可以查看到新插入的数据,如图所示。9.2初始化云开发环境在可以进行云开发之前,需要首先初始化云开发环境,使用如下语句初始化云开发环境:wx.cloud.init();一般而言,只需初始化一次云开发环境,因此,语句:wx.cloud.init();只需要调用一次。初始化云开发环境的最佳实践是:将初始化云开发环境的代码放置在app.js文件中,就像下面这个app.js文件一样://app.jsApp({onLaunch(){wx.cloud.init();}})9.3云数据库云开发提供了一个JSON数据库,顾名思义,数据库中的每条记录都是一个JSON对象。一个数据库可以有多个集合(一个集合就相当于关系型数据中的表),一个集合就是一个JSON数组,数组中的每个对象就是一条记录,每条记录本质上就是一个JSON对象。类似于对传统的关系型数据库的数据操作,可以对云数据库中的数据进行简单的增删改查操作,也可以对云数据库进行复杂的聚类分组操作。不同于关系型数据库,微信云数据库规定:每条记录都自动包含名称为“_id”的字符串字段,该字段可以唯一标识一条记录;每条记录还会自动包含一个名称为“_openid”的字段,这个字段唯一标识记录的创建者。在云数据库中,为了数据安全考虑,只有数据记录的创建者才可以修改和删除自己创建的数据记录。在可以使用云数据库之前,也需要初始化云开发数据库,使用如下语句初始化云数据库环境:constdb=wx.cloud.database();9.3.1数据类型云数据库提供了对基本数据类型的支持。云数据库支持的数据类型及其含义如下:string:字符串;number:数字;object:对象;array:数组;boolean:布尔值;date:时间;geopoint:多种地理位置类型;null。其中的date类型表示时间,精确到毫秒,在小程序端可用JavaScript内置Date对象创建;null相当于一个占位符,表示一个字段存在但是值为空。在云开发的控制台上,可以查看目前云数据库所支持的所有数据类型。如图所示:9.3.2新建集合和数据访问权限控制在可以向云数据库集合进行数据的增删改查之前,需要先在云数据库中创建集合。为此,在云开发控制台,点击“数据库”按钮,如图所示。为了保证云数据库数据安全,点击箭头3所指向的“数据权限“按钮设置数据集合的访问权限,如图所示。9.3.3插入数据可以通过在集合对象上调用add方法往集合中插入一条记录。例如,以goods集合为例,可以使用如下语句向集合插入一条记录:db.collection(goods).add({//data字段表示需新增的JSON数据data:{//_id:数据库自动分配,无须给值name:"笔记本电脑",price:6780,producer:{"name":“联想P14s”"date":“2020-10-21”},//该电脑目前所在位置(113°E,23°N)location:newdb.Geo.Point(113,23)},success:function(res){//res是一个对象,其中有_id字段标记刚创建的记录的_idconsole.log(res)}})当然,也可以使用Promise风格向集合插入数据,例如:db.collection(goods).add({//data字段表示需新增的JSON数据data:{//_id:数据库自动分配,无须给值name:"电子白板",price:2180,user:“张三”}}).then(res=>{console.log(res)})9.3.4修改数据微信提供了两种修改数据(更新数据)的方式:其一,使用update()方法局部更新一个或多个记录;其二,使用set()方法替换更新整个记录。1、使用update()方法更新局部数据使用update()方法可以局部更新一个记录或一个集合中的记录,局部更新意味着只有指定的字段会得到更新,其他字段不受影响。例如,下面的例子修改指定_id记录的price字段的值为3030:db.collection(goods).doc('06019505661dcca0077253e2775e9bb5').update({//data传入需要局部更新的数据data:{//表示将price字段置为3030price:3030},success:function(res){console.log(res.data)}})集合的.doc()方法指定要操作的数据的_id。除了用指定值更新字段外,数据库API还提供了一系列的更新指令用于执行更复杂的更新操作,所支持的更新指令包含在mand对象中,如表所示。序号更新指令含义1set(value:any)更新操作符,用于设定字段等于指定值2remove()更新操作符,用于表示删除某个字段3inc(value:number)更新操作符,原子操作,用于指示字段自增4mul(value:number)更新操作符,原子操作,用于指示字段自乘某个值5push(values:Object)数组更新操作符。对一个值为数组的字段,往数组添加一个或多个值;或字段原为空,则创建该字段并设数组为传入值6pop()数组更新操作符,对一个值为数组的字段,将数组尾部元素删除7shift()数组更新操作符,对一个值为数组的字段,将数组头部元素删除8unshift(values:any[])数组更新操作符,对一个值为数组的字段,往数组头部添加一个或多个值;或字段原为空,则创建该字段并设数组为传入值。9max(value:any)更新操作符,给定一个值,只有该值大于字段当前值才进行更新10min(value:any)更新操作符,给定一个值,只有该值小于字段当前值才进行更新例如,如果要将goods集合中指定的_id记录的price字段的值增加100,可使用如下代码:const_=mand;db.collection(goods).doc('06019505661dcca0077253e2775e9bb5').update({data:{//将price字段自增100price:_.inc(100)},success:function(res){console.log(res.data)}});再举一个例子。这个例子对goods的指定记录新增一个category数组字段,同时,检查价格是否小于3000,若是,则将价格修改为3000:const_=mand;db.collection(goods).doc('06019505661dcca0077253e2775e9bb5').update({data:{//检查价格是否小于3000,若是,则将价格修改为3000price:_.max(3000),category:_.push([‘电子商品’,‘消费品’])},success:function(res){console.log(res.data)}});特别提醒:客户端只能对指定_id的记录进行修改操作。如果需要更新多个数据,则需要在云端进行操作(也就是需要使用云函数才可以一次性修改/删除多条记录),在云端的where语句后可以调用update方法对数据记录进行修改。例如,下面的例子对价格小于3000的商品的价格提升20%://使用了asyncawait语法constcloud=require('wx-server-sdk');constdb=cloud.database();const_=mand;
exports.main=async(event,context)=>{try{returnawaitdb.collection(goods).where({price:_.lt(3000)}).update({data:{price:_.mul(0.2)},})}catch(e){console.error(e)}}2、使用set()方法替换整条数据使用set()方法可以替换更新一整条记录,替换更新意味着用传入的对象替换指定的记录,如下面的例子,使用新的记录替换原来的一整条的记录数据:const_=manddb.collection('goods').doc('06019505661dcca0077253e2775e9bb5').set({data:{name:"智能机器人",price:56000,due:newDate("2018-09-01"),tags:["cloud","database"],style:{color:"skyblue"}},success:function(res){console.log(res.data)}})9.3.5删除数据使用remove()方法删除从云数据库删除数据记录。在客户端,也就是在微信小程序端只能基于给定的_id一次删除一条数据记录,若要一次性删除多条记录,则需要在云端(也就是使用云函数)完成。例如,使用如下的语句可以从goods集合中删除给定_id的记录:db.collection('goods').doc('06019505661dcca0077253e2775e9bb5').remove({success:function(res){console.log(res.data)}})如果需要删除多个数据,需在云端进行操作(云函数)。可通过where语句选取多条记录执行删除。例如,下面的云函数删除价格小于3000的商品记录://使用了asyncawait语法constcloud=require('wx-server-sdk')constdb=cloud.database()const_=mand
exports.main=async(event,context)=>{try{returnawaitdb.collection('goods').where({price:_.lt(3000)}).remove()}catch(e){console.error(e)}}9.3.6查询数据使用get()方法从云数据库集合获取数据。可以使用集合的.doc()方法指定要查询的数据记录,例如,下面的例子查询并返回给定_id的记录:或者,也可以使用Promise风格获取数据记录:db.collection('goods').doc('06019505661dcca0077253e2775e9bb5').get({success:function(res){//res.data包含该记录的数据console.log(res.data)}})db.collection('goods').doc('06019505661dcca0077253e2775e9bb5').get().then(res=>{//res.data包含该记录的数据console.log(res.data)})在集合上使用where()方法可以一次查询得到多条记录。例如,下面的代码将查询所有价格大于3000的记录:where()方法接收一个对象参数,该对象中每个字段和它的值构成一个需满足的匹配条件,各个字段间的关系是"与"的关系,即需同时满足这些匹配条件,在这个例子中,就是查询出goods集合中_openid等于user-open-id且price大于3000的记录。const_=mand;
db.collection('goods').where({_openid:'user-open-id',price:_.gt(3000)}).get({success:function(res){//res.data是包含满足条件的记录数组console.log(res.data)}})与数据更新操作类似,数据库API也提供了一系列的查询指令用于执行复杂的查询操作,所支持的查询指令包含在mand对象中,如表:序号查询指令含义1eq(value:any)查询筛选条件,表示字段等于某个值。eq指令接受一个字面量(literal),可以是number,boolean,string,object,array,Date等2neq(value:any)查询筛选条件,表示字段不等于某个值。neq指令接受一个字面量(literal),可以是number,boolean,string,object,array,Date等3lt(value:any)查询筛选操作符,表示需小于指定值。可以传入Date对象用于进行日期比较。4lte(value:any)查询筛选操作符,表示需小于或等于指定值。可以传入Date对象用于进行日期比较。5gt(value:any)查询筛选操作符,表示需大于指定值。可以传入Date对象用于进行日期比较。6gte(value:any)查询筛选操作符,表示需大于或等于指定值。可以传入Date对象用于进行日期比较。7in(value:any[])查询筛选操作符,表示要求值在给定的数组内。8nin(value:any[])查询筛选操作符,表示要求值不在给定的数组内。9and(expressions:any[])查询操作符,用于表示逻辑"与"的关系,表示需同时满足多个查询筛选条件10or(expressions:any[])查询操作符,用于表示逻辑"或"的关系,表示需满足多个查询筛选条件的至少一个。或指令有两种用法,一是可以进行字段值的“或”操作,二是也可以进行跨字段的“或”操作。例如,下面的例子通过使用and指令查询价格大于2000并且小于3000的所有记录:const_=manddb.collection('goods').where({//and方法用于指定一个"与"条件,此处需同时满足_.gt(2000)和_.lt(3000)两个条件price:_.gt(2000).and(_.lt(3000))}).get({success:function(res){console.log(res.data)}})使用and指令、or指令还可以实现跨字段的逻辑运算。例如,下面的例子查询价格大于6000或者名字是”电冰箱”的所有商品:const_=manddb.collection('goods').where(_.or([{price:_.gt(6000)},{name:“电冰箱”}])).get({success:function(res){console.log(res.data)}})如果要获取一个集合的所有数据,可以在集合上调用get()方法获取,但通常不建议这么使用,在小程序中我们需要尽量避免一次性获取过量的数据,只应获取必要的数据。为了防止误操作以及保护小程序体验,小程序端在获取集合数据时服务器一次默认并且最多返回20条记录,云函数端这个数字则是100。开发者可以结合skip()方法和limit()方法指定需要获取的记录数量,但小程序端不能超过20条,云函数端不能超过100条。例如,下面的这段代码以分页的方式返回指定页的数据记录:constPAGE=20;page=2;//获取第几页数据db.collection('goods').skip(page*PAGE).limit(PAGE).get({success:function(res){console.log(res.data)}})9.3.7云数据库核心对象和核心方法总览本节对云数据库操作的核心方法和核心对象进行总览介绍。在小程序可以操作云数据库之前,需要调用cloud.database(options:Object):Database方法获得云数据库的引用实例。该方法接受一个对象参数,该对象参数的属性及其含义如表:序号属性名类型默认值必填说明1envstring无否环境ID,若不填则采用wx.cloud.init中的值2throwOnNotFoundbooleantrue否在调用获取记录(doc.get)时,如果获取不到,是否抛出异常,如果不抛出异常,doc.get返回空。默认true。例如,下面的语句将获取默认云环境的云数据库引用:constdb=wx.cloud.database();方法wx.cloud.database()返回的是一个云数据库Database对象引用,通过这个对象可完成对云数据库的操作。Database对象常用属性、方法及其含义如表:序号属性名称/方法原型属性/方法含义1Commandcommand属性数据库操作符,参见表9-1和表9-22GeoGeo属性数据库地理位置结构3Database.collection(name:string):Collection方法获取集合的引用。方法接受一个name参数,指定需引用的集合名称。4Database.createCollection(collectionName:string):Promise<Object>方法创建集合,如果集合已经存在会创建失败5Database.serverDate(options:Object):ServerDate方法构造一个服务端时间的引用。可用于查询条件、更新字段值或新增记录时的字段值6Database.runTransaction(callback:function,times:number):Promise<any>
方法发起事务。仅可在云函数中使用7Database.startTransaction():Promise<Transaction>
方法开始事务,另一个同样可以使用的发起事务的API是runTransaction。仅可在云函数中使用。调用Database.collection(name:string)获取云数据库一个集合的引用,该方法返回一个Collection对象。Collection对象常用属性、方法及其含义如表:序号属性名称/方法原型属性/方法含义1Collection.doc(id:string):Document方法获取集合中指定记录的引用。方法接受一个id参数,指定需引用的记录的_id2Collection.add(options:Object):Promise<Object>方法新增记录,如果传入的记录对象没有_id字段,则由后台自动生成_id;若指定了_id,则不能与已有记录冲突3Collection.aggregate():Aggregate方法发起聚合操作,定义完聚合流水线阶段之后需调用end方法标志结束定义并实际发起聚合操作4Collection.count():Promise<Object>方法统计匹配查询条件的记录的条数5Collection.field(projection:Object):Collection方法指定返回结果中记录需返回的字段6Collection.get():Promise<Object>方法获取集合数据,或获取根据查询条件筛选后的集合数据7Collection.limit(value:number):Collection方法指定查询结果集数量上限8Collection.orderBy(fieldPath:string,string:order):Collection方法指定查询排序条件9Collection.remove():Promise<Object>方法删除多条记录。注意只支持通过匹配where语句来删除,不支持skip和limit10Collection.skip(offset:number):Collection方法指定查询返回结果时从指定序列后的结果开始返回,常用于分页11Collection.update():Promise<Object>方法更新多条记录12Collection.where(condition:Object):Collection方法指定查询条件,返回带新查询条件的新的集合引用调用Collection.doc(id:string)方法将返回一个Document对象,该Document对象的常用属性、方法及其含义如表:序号属性名称/方法原型属性/方法含义1Document.get():Promise<Object>方法获取记录数据,或获取根据查询条件筛选后的记录数据2Document.remove():Promise<Object>方法删除一条记录3Document.set(options:Object):Promise<Object>方法替换更新一条记录4Document.update(options:Object):Promise<Object>方法更新一条记录9.4云存储微信云开发环境为小程序提供了高可用和高稳定的云存储空间,小程序可以在这个存储空间中可以创建文件夹、可以存储包括图像、视频在内的任何文件。小程序可以向访问任何本地或者网络文件资源一样访问存储与云空间的云文件,同时,用户可以在云开发控制台对存储与云存储中的文件进行管理。9.4.1上传文件到云存储小程序端可调用wx.cloud.uploadFile(Objectoptions)方法上传本地文件到云存储中。该方法接受一个对象作为参数,其对象参数的属性及其含义如表:序号属性名类型默认值必填说明1cloudPathString无是云存储路径2filePathString无是要上传文件资源的路径3configObject无否环境配置。该对象包含如下属性:env,String,使用的环境ID,填写后忽略init指定的环境ID4successfunction无否成功回调。接受一个Object对象参数,该对象包含以下属性:fileID,String,文件ID;statusCode,Number,服务器返回的HTTP状态码;errMsg,String,错误信息5failfunction无否失败回调。接受一个Object对象参数,该对象包含以下属性:errCode,错误码,Number;errMsg,String,错误信息6completefunction无否结束回调例如,下面的代码上传指定的本地文件到云存储:wx.cloud.uploadFile({cloudPath:'example.png',//在云存储中的文件名称filePath:'本地文件路径',//文件路径success:res=>{//显示云文件的IDconsole.log(res.fileID)},fail:err=>{//进行错误处理}})当然,上面这段代码特可以采用Promise风格:上传到云存储的每个文件都有一个唯一的“FileID”,通过这个FileID可以下载云文件。或者对于图像文件,可以显示在微信的image组件中。wx.cloud.uploadFile({cloudPath:'example.png',//在云存储中的文件名称filePath:'本地文件路径',//文件路径}).then(res=>{//显示云文件的IDconsole.log(res.fileID)}).catch(error=>{//进行错误处理})9.4.2从云存储下载文件对云存储中的文件,可以使用wx.cloud.downloadFile(Objectoptions)方法下载到本地。该方法接受一个Object的对象参数,该对象参数的属性及其含义如表:序号属性名类型默认值必填说明1fileIDString无是云文件ID 2configObject无否环境配置。该对象包含如下属性:env,String,使用的环境ID,填写后忽略init指定的环境ID3successfunction无否成功回调。接受一个Object对象参数,该对象包含以下属性:tempFilePath,String,临时文件路径;statusCode,Number,服务器返回的HTTP状态码;errMsg,String,错误信息4failfunction无否失败回调。接受一个Object对象参数,该对象包含以下属性:errCode,错误码,Number;errMsg,String,错误信息5completefunction无否结束回调例如,下面的代码从云存储上下载指定FileID的文件,并显示现在到本地后的保存文件的临时路径:wx.cloud.downloadFile({fileID:'cloud://teaching-8g682.7465-teaching-8g6ab8a30c-1320566453/example.png',success:res=>{//gettempfilepathconsole.log(res.tempFilePath)},fail:err=>{//handleerror}})9.4.3删除云存储中的文件可以使用Cloud.deleteFile(fileList:string[]):Promise<Object>删除云存储中指定FileID的文件。该函数的参数为云文件ID字符串数组,最多一次删除50个云文件。该函数返回一个Promise对象,该对象接受一个Object对象参数,这个Object参数包括一个名称为fileList的属性,这是一个数组,通过这个属性即可得到每个云文件的删除结果。例如,下面的代码删除指定的云文件:wx.cloud.deleteFile({fileList:['cloud://aasd7xzcb-12332scxcvxcvvcx-wewexzvxvcxvcxxcv',‘cloud://teaching-8g682.7465-teaching-8g6ab8a30c-1320566453/example.png’]}).then(res=>{//handlesuccessconsole.log(res.fileList)}).catch(error=>{//handleerror})9.4.4引用云文件可以在image、audio等组件中传入云文件ID,进而可以在图像组件显示云存储中的图像文件,或者,可以在audio组件中播放存储与云存储中的音频。例如,下面WXML代码将显示存储于云端的图像:<image
src="cloud://teaching-8g682zowbab8a30c.7465-teaching-8g682zowbab8a30c-1320566453/example.png"
mode="widthFix"></image>9.5云函数云函数,顾名思义,就是在云端(也就是服务器端)运行的函数。云函数代码运行在云服务器的Node.js中,因此,云函数被小程序调用时,云函数代码会在云端的Node.js环境中执行。在云函数中可以进行网络请求等操作,还可以在云函数中进行云数据库和云存储相关的操作。9.5.1配置云函数环境在进行云函数开发之前,需要在小程序工程中创建一个为存放云函数的目录。一个不成文的规定是:新建cloudfunctions作为云函数存储目录,为此,在小程序的工程根目录上新建名称为“cloudfunctions”的子目录。然后,在小程序工程的根目录下的配置文件project.config.json中新增cloudfunctionRoot字段,指定已存在的目录作为云开发的本地根目录,如下代码所示:"cloudfunctionRoot":"cloudfunctions/"最后,右击cloudfunctions目录,选择“当前环境”选项,在列出的选项中选择在开通云开发时所命名的云开发环境的名称,完成指定之后,云开发根目录的图标会变成“云开发图标”。如图所示。9.5.2新建云函数举一个例子说明如何创建和调用云函数。这个例子完成两个整数的相加并将结果返回给调用者。命名这个云函数为add。为了新建云函数,在云函数根目录上右键,在右键菜单中,选择“新建Node.js云函数”菜单项,将该云函数命名为add。开发者工具将在本地云函数目录创建云函数目录和入口index.js文件,同时在线上环境中创建出对应的云函数:一个云函数本质上就是在cloudfunctions目录下新建一个以云函数名称命名的子目录,在该子目录下有三个文件,名称分别为config.json、index.js和package.json。其中,index.js就是可执行的JavaScript云函数代码。新建的index.js文件为如下模板内容://云函数入口文件constcloud=require('wx-server-sdk')
cloud.init()
//云函数入口函数exports.main=async(event,context)=>{constwxContext=cloud.getWXContext()
return{event,openid:wxContext.OPENID,appid:wxContext.APPID,unionid:wxContext.UNIONID,}}云函数的传入参数有两个,一个是event对象,一个是context对象。event指的是触发云函数的事件,当小程序端调用云函数时,event就是小程序端调用云函数时传入的参数,外加后端自动注入的小程序用户的openid和小程序的appid。现在修改index.js文件为如下内容://云函数入口文件constcloud=require('wx-server-sdk')cloud.init({env:cloud.DYNAMIC_CURRENT_ENV})//使用当前云环境//云函数入口函数exports.main=async(event,context)=>{return{sum:event.a+event.b}}在微信开发者工具中保存index.js文件,然后,右键该add云函数,选择“上传并部署:云端安装依赖(不上传nodemodules)”菜单项将新修改的代码上传到云端,如图所示。9.5.3在小程序中调用云函数对于已经完成开发和完成部署的云函数,可以在小程序中调用和使用它们。例如,对于上一节的add云函数,可以使用如下的代码调用它:wx.cloud.init();//初始化云开发环境。只需要调用一次wx.cloud.callFunction({name:'add',//要调用的云函数名称//要传给云函数的参数data:{a:1,b:2,},success:function(res){console.log(res.result.sum)//结果应该是3},fail:console.error})当然,也可以使用如下的Promise风格调用云函数:wx.cloud.init();//初始化云开发环境。只需要调用一次wx.cloud.callFunction({name:'add',//要云函数名称//传给云函数的参数data:{a:1,b:2,},}).then(res=>{console.log(res.result)//3}).catch(console.error)9.5.4在云函数中进行云操作云函数属于管理端,在云函数中运行的代码拥有不受限的数据库读写权限和云文件读写权限。wx-server-sdk库以与小程序端云API类似的风格提供了云函数访问云数据库、云存储和云函数的API。可以在云函数中访问云数据库、操作云文件之前,需要使用如下语句导入必须的函数库和初始化云环境:或者:constcloud=require('wx-server-sdk')//给定字符串环境ID,或者不给出环境ID参数,从而使用默认环境cloud.init({env:'some-env-id'})constcloud=require('wx-server-sdk')//给定DYNAMIC_CURRENT_ENV常量:使用与该云函数当前所在环境相同的环境cloud.init({env:cloud.DYNAMIC_CURRENT_ENV})1、在云函数中访问云数据库假设在数据库中已有一个goods集合,那么可以在云函数中以如下方式取得goods集合的数据:constcloud=require('wx-server-sdk')cloud.init({env:cloud.DYNAMIC_CURRENT_ENV})
constdb=cloud.database()exports.main=async(event,context)=>{//collection的get方法返回Promise,因此云函数在数据库异步取完数据后返回结果returndb.collection('goods').get()}2、云函数中操作云存储在云函数中可以操作云存储中的文件。例如,下列的代码将删除云存储中指定云文件ID的云文件:constcloud=require('wx-server-sdk')cloud.init({env:cloud.DYNAMIC_CURRENT_ENV})
exports.main=async(event,context)=>{returncloud.deleteFile({fileList:['cloud://aasd7xzcb-12332scxcvxcvvcx-wewexzvxvcxvcxxcv',‘cloud://teaching-8g2.7465-teaching-8g6ab8a30c-1320566453/example.png’]});3、云函数中调用其他云函数在云函数中可以调用其他云函数。例如,下面的这个云函数调用另一个名称为add的云函数,将add云函数的结果加上100后再返回结果:constcloud=require('wx-server-sdk')cloud.init({env:cloud.DYNAMIC_CURRENT_ENV})
exports.main=async(event,context)=>{leta=awaitcloud.callFunction({name:'sum',data:{x:1,y:2,}});letb=a+100;returnb;}9.5.5在云函数中获取小程序用户信息云函数的独特优势在于与微信登录鉴权的无缝整合。当小程序端调用云函数时,云端会自动将openid注入到云函数的上下文对象参数中,与openid一起注入的还有小程序的appid。在云函数中,可以使用wx-server-sdk提供的getWXContext方法获取到appid、openid、openid等信息。例如下面的云函数将用户鉴权相关数据返回给小程序://index.js//云函数入口文件constcloud=require('wx-server-sdk')cloud.init({env:cloud.DYNAMIC_CURRENT_ENV})//使用当前云环境
//云函数入口函数exports.main=async(event,context)=>{constwxContext=cloud.getWXContext()return{event,openid:wxContext.OPENID,appid:wxContext.APPID,unionid:wxContext.UNIONID,}}假设这个云函数命名为spec,将云函数上传并部署到云端后,可在如下的小程序中代码中调用该云函数并显示用户鉴权相关数据:wx.cloud.callFunction({name:'spec',complete:res=>{console.log('callFunctionspecresult:',res)}})为了观察使用云函数获取用户鉴权数据的便利性,下面举例子说明这个问题。为此,首先在微信开发者工具中新建名称为mini-ch09-02的工程,然后在工程的根目录下新建名称为cloudfunctions的子目录用于存放云函数,在project.config.json文件中添加设置云函数目录配置,如下代码所示:"cloudfunctionRoot":"cloudfunctions/",最后设置相关云环境,结果如图所示。首先,初始化小程序云开发环境,为此,修改app.js为如下代码://app.jsApp({onLaunch(){wx.cloud.init();}})在cloudfunctions云函数目录下新建名称为spec的Node.js云函数,修改spec云函数的index.js代码为如下内容://云函数入口文件constcloud=require('wx-server-sdk')cloud.init({env:cloud.DYNAMIC_CURRENT_ENV})//使用当前云环境
//云函数入口函数exports.main=async(event,context)=>{constwxContext=cloud.getWXContext()return{event,openid:wxContext.OPENID,appid:wxContext.APPID,unionid:wxContext.UNIONID,}}修改index.wxml为如下内容:<!--index.wxml--><navigation-bartitle="Weixin"back="{{false}}"color="black"background="#FFF"></navigation-bar><scroll-viewclass="scrollarea"scroll-ytype="list"><viewclass="container"><text>openid:{{openid}}\nappid:{{appid}}\nunionid:{{unionid}}</text></view></scroll-view>index.js的代码如下://index.jsPage({data:{openid:'',appid:'',unionid:''},onReady(){letthat=this;wx.cloud.callFunction({//云函数名称name:'spec',success(res){console.log(res.result);that.setData({openid:res.result.openid,appid:res.result.appid,unionid:res.result.unionid})},fail(){console.error();}})},})运行这个程序,显示如图所示的结果。9.6案例:在线竞选班长随着信息技术手段的不断发展,竞选班长的方式也发生了变化:可以开发一个简单的微信小程序协助进行班长竞选。本节通过一个称为“在线竞选班长”的微信小程序开发例子对本章的内容进行总结和应用。9.6.1案例目标作为一个可以完成在线竞选班长的微信小程序,在程序功能上,首先竞选人可以录入自己竞选信息,其次,选举人可以查看竞选人信息并进行投票。因此,在这个小程序的首页面上,用户可以选择“我要竞选”及“我要投票”功能选项完成竞选人信息录入功能和对竞选人进行投票功能。9.6.2案例分析该小程序包括三个页面:首页面,在首页面上,用户可以选择“我要竞选”及“我要投票”功能选项并进入相应页面;“我要竞选”功能页面,在这个页面中,用户可以录入个人竞选信息,进而可以作为竞选人参与竞选;“我要投票”功能页面,用户可以查看所有竞选人信息并根据自己的意愿投票。考虑到开发系统的简便性,将竞选人信息和投票结果信息保存到云数据库。总结起来,这个小程序需要完成如下开发工作:1、 设计和开发主页面程序,命名为index页面;2、 设计和开发“我要竞选”功能页面,命名为candidate页面;3、 设计和开发“我要投票”功能页面,命名为elect页面;4、 设计云端候选人集合,用于保存候选人信息和选票计数,命名集合为leader;9.6.3案例实施新建名称为mini-ch09-03的小程序工程,在工程根目录下新建名称为cloudfunctions的子目录用于存放云函数。修改project.config.json配置文件,增添如下配置语句:"cloudfunctionRoot":"cloudfunctions/",并选择云开发环境为teaching环境。如图所示。修改app.js为如下内容:在app.json的pages属性中添加如下页面,也就是新增两个页面:修改candidate页面和elect页面的json文件均为如下内容,也就是新增的两个页面均使用自定义的navigation-bar进行导航://app.jsApp({onLaunch(){wx.cloud.init();}})"pages/candidate/candidate","pages/elect/elect"{"usingComponents":{"navigation-bar":"/components/navigation-bar/navigation-bar"}}现在修改主页面index.wxml文件为如下内容:<!--index.wxml--><navigation-bartitle="Weixin"back="{{false}}"color="black"background="#FFF"></navigation-bar><scroll-viewclass="scrollarea"scroll-ytype="list"><view><buttonstyle="width:90%;margin:10px;"type="primary"bind:tap="tap"data-who="1">我要竞选</button><buttonstyle="width:90%;margin:10px;"type="primary"bind:tap="tap"data-who="2">我要投票</button></view></scroll-view>修改index.js代码为如下内容://index.jsPage({tap(e){if(e.target.dataset.who=='1'){wx.navigateTo({url:'../candidate/candidate',})}else{wx.navigateTo({url:'../elect/elect',})
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 中信期货佛山分公司2026届校园招聘备考题库附答案详解(培优a卷)
- 2026年来安县公开招聘2名政府购买服务工作人员备考题库附答案详解(巩固)
- 2026清华大学出版社校园招聘备考题库及答案详解【新】
- 2026浙江大学宁波国际科创中心未来计算技术创新中心工程师招聘备考题库含答案详解(完整版)
- 2026越秀地产春季校园招聘备考题库及答案详解(网校专用)
- 2026重庆建筑工程职业学院招聘非事业编制(合同制)人员1人备考题库(第一批)及答案详解【考点梳理】
- 2026江西赣西科技职业学院人才招聘备考题库附答案详解(基础题)
- 2026新疆塔城地区检察机关面向社会考试招聘聘用制书记员13人备考题库附参考答案详解(能力提升)
- 2026浙江宁波市镇海区急救中心编外人员招聘1人备考题库及参考答案详解(基础题)
- 2026广东湛江市吴川市公益性岗位人员招聘5人备考题库及参考答案详解(典型题)
- 长螺旋钻干作业引孔静压PHC管桩施工工法
- 七上英语人教新版阅读短文填空小纸条
- 有机合成实验室安全培训课件
- 企业资产交接流程及确认书范本
- 2025年肾病科慢性肾脏病药物治疗考核答案及解析
- 小米智能家居营销策略
- (2025年标准)生意入股合同协议书
- 2024年广东东莞东华高级中学自主招生数学试卷(含答案详解)
- 《安宁疗护》高职护理专业全套教学课件
- 中央空调机房管理制度
- (高清版)DB2105∕T 016-2024 林下朝鲜淫羊藿种植技术规程
评论
0/150
提交评论