微信小程序开发(二)----- 云开发
1、概念
- 微信小程序的云开发是腾讯云与微信团队深度合作推出的一个全新的小程序的解决方案,它提供了云函数、云数据库与云存储这三大基础能力支持,随着云开发的出现,小程序的开发者可以将服务端的部署和运营的环节进行服务端的托管,让腾讯云去管理,而不需要在运维和管理方面投入太多的精力。
2、传统小程序开发与云开发的区别
- 小程序传统开发模式:(开发效率低、运维成本高)
对于小程序传统的开发模式而言,我们需要一个客户端(也就是前端页面),而前端页面展示的数据大多来自于数据库,因此我们还需要一个服务端,把后端的代码以及数
据库部署上去,并且前后端联调的过程也是沟通的过程,时间成本比较高;小程序在部署的时候,我们需要购买相对应的域名以及服务器,并且还要进行备案(非常麻烦、耗时长),
部署成功后,在运维小程序的过程中,也会遇到很多很多的问题,比如DB运维、文件存储、内容加速(CDN)、网络防护、容器服务、负载均衡以及安全加固等;虽然有的公司没有
购买服务器,使用的是阿里云或者腾讯云上面的服务,但是依旧需要维护,因此运维成本非常高。
- 小程序云开发模式:采用serverless(无服务)模式
对于小程序的云开发模式而言,依旧需要一个客户端,但是由于小程序提供了云开发,而云开发提供了云函数、云数据库以及云存储三大基础能力支持,我们可以直接在客户
端调用云数据库里面的内容,当然也可以通过客户端调用云函数,在云函数里面处理一些业务逻辑,并在云函数里面调用云数据库,同时我们可以在客户端上传相应的文件到云存储当
中,或者将云存储中的图片下载到客户端给用户去展示,由于云开发是部署在腾讯云上面的,因此我们不需要额外的运维人员,运维成本也会降低。除此之外,小程序中的云函数采用
的是Node.js,云数据库采用的是mongoDB,而node调用mongoDB也是很方便的。
- 三大基础能力支持:
- 云数据库:是一个JSON数据库(文档型数据库),提供了2GB的免费存储空间,实现对数据的增删改查的操作;
- 支持的数据类型:Number、String、Object、Array、Boolean、Date、Null以及GeoPoint(地理位置点);
- 如何通过代码操作数据库:
- 初始化:
const db = wx.cloud.database()
- 切换环境
const testDB = wx.cloud.database({
env: 'test'//环境名称
}) - 简单数据的增删改查
- WXML
<view>数据库的增删改查</view>
<button size="mini" catchtap="onCatchPostHandler">增加</button>
<button size="mini" catchtap="onCatchDeleteHandler">删除</button>
<button size="mini" catchtap="onCatchUpdateHandler">修改</button>
<button size="mini" catchtap="onCatchGetHandler">查找</button> - JS
// 数据库的初始化
const db = wx.cloud.database(); Page({ /**
* 页面的初始数据
*/
data: { },
/**
* 数据库的添加
*/
onCatchPostHandler() {
// 回调函数写法
/**
* db.collection('user').add({
data: {
name: 'wxh',
age: '18',
job: 'IT'
},
success: (res) => {
// 使用了ES6中的箭头函数,目的是为了改变this指向
console.log(res)
},
fail: (error) => {
console.log(error)
}
})
*/
// promise的写法
db.collection('user')
.add({
data: {
name: 'jerry',
age: '',
job: 'teacher'
}
})
.then((res) => {
console.log(res)
})
.catch((error) => {
console.log(error)
})
},
/**
* 数据库的删除
*/
onCatchDeleteHandler() {
// 删除一条可以通过小程序端进行控制,而删除多条我们需要小程序调用云函数来操作数据库
db.collection('user')
.doc("b040a67a5df1f6d1029170ef7e785160")
.remove()
.then((res) => {
console.log(res)
})
.catch((error) => {
console.log(error)
})
},
/**
* 数据库的修改
*/
onCatchUpdateHandler() {
db.collection('user')
.doc('b040a67a5df1f6d1029170ef7e785160')
.update({
data: {
age: ''
}
})
.then((res) => {
console.log(res)
})
.catch((error) => {
console.log(error)
})
},
/**
* 数据库的查找
*/
onCatchGetHandler() {
db.collection('user')
.where({
name: 'wxh'
})
.get({})
.then((res) => {
console.log(res)
})
.catch((error) => {
console.log(error)
})
}, - 注意:如果是在数据库手动加入记录,会出现查不到的情况,这个时候我们需要设置
- WXML
- 初始化:
- 云数据库:是一个JSON数据库(文档型数据库),提供了2GB的免费存储空间,实现对数据的增删改查的操作;
- 三大基础能力支持:
- 云函数:相当于小程序在服务端的后台代码,可以非常方便的获取到当前登录用户的信息(appid、openid、生成分享图或者调用腾讯云的SDK);
- 去Node官网(http://nodejs.cn/),安装Node环境(需要nodev8.0及以上版本);
- 安装成功的标志:windows+r,输入cmd, 打开命令输入 node -v 显示版本号;
- 云函数:相当于小程序在服务端的后台代码,可以非常方便的获取到当前登录用户的信息(appid、openid、生成分享图或者调用腾讯云的SDK);
- 创建云函数
- 很有可能提醒是否需要安装wx-server-sdk ----- > 点击确定;
- 每次修改云函数都需右键点击“上传并部署,云端安装依赖”;
- 在调用云函数的过程中提示没有安装wx-server-sdk包,这个时候在cloudfunctions中,右键在终端打开,输入安装命令npm install --save wx-server-sdk@latest(表示安装最新版本)
- 简单的调用一个云函数:求a+b的和;
- sum下的index.js
// 云函数入口函数
exports.main = async (event, context) => {
// event 中包括小程序调用云函数传过来的对象
// context 指当前调用的上下文,同时也包括当前用户的一些信息
return {
sum: event.a + event.b
}
} <button catchtap="onCatchSumHandler" size="mini">调用云函数sum</button>
/**
* 云函数的调用
*/
onCatchSumHandler() {
wx.cloud
.callFunction({
name: 'sum',//当前云函数的名称
data: {
a: ,
b:
}
})
.then((res) => {
console.log(res)
})
.catch(error => {
console.log(error)
})
},
- sum下的index.js
- 获取当前用户的openid:
- 传统的微信登录方式与小程序云开发登录方式的区别:
- 传统的微信登录方式
首先用户端小程序通过调用wx.login,从微信服务端获取一个code,然后用户小程序端调用wx.request将code传递给后端服务器,后端
获得到code之后,对微信服务端发起请求,通过code获取openid与session_key,最后将小程序的唯一标识发送给小程序本地存储。 - 小程序云开发登录方式
用户通过点击按钮,从小程序获取用户的信息,而小程序通过云函数获得用户的信息,云函数给小程序端返回用户的openid,小程序获取到
用户的信息之后,将用户的信息存储到云数据库。
- 传统的微信登录方式
- 云函数会自带一个login文件夹,它的作用就是获取当前用户的信息;
<button catchtap="onCatchOpenIdHandler" size="mini">获取当前用户openid</button> /**
* 获取当前用户的openid
*/
onCatchOpenIdHandler() {
wx.cloud
.callFunction({
name: 'login',
})
.then((res) => {
console.log(res)
})
.catch((error) => {
console.log(error)
})
},
- 传统的微信登录方式与小程序云开发登录方式的区别:
- 批量删除
- 定义云函数batchDelete
// 云函数入口文件
const cloud = require('wx-server-sdk') cloud.init() // 获取云数据库
const db = cloud.database(); // 云函数入口函数
exports.main = async (event, context) => {
// 数据库是一个异步的操作,等到删除成功或者失败才可以返回数据给小程序 因此需要ES7的await
try {
return await db.collection('user')
.where({
name: event.name
})
.remove();
}
catch (error) {
console.log(error)
}
} - 调用云函数
<button catchtap="onCatchBatchDeleteIdHandler" size="mini">批量删除数据</button> /**
* 批量删除
*/
onCatchBatchDeleteIdHandler() {
wx.cloud.callFunction({
name: 'batchDelete',
data: {
name: 'wxh'
}
}).then((res) => {
console.log(res)
}).catch((error) => {
console.log(error)
})
},
- 定义云函数batchDelete
- 云存储:管理、上传、下载以及分享文件等操作;
- 云存储能力
- wx.cloud.uploadFile ----- 上传文件
- 步骤示意图
- wx.cloud.uploadFile ----- 上传文件
- 云存储能力
- 云存储:管理、上传、下载以及分享文件等操作;
- 上传并展示的代码
<view>云存储</view>
<button catchtap="onCatchUploadHandler">上传图片</button>
<button catchtap="onCatchShowHandler">展示图片</button>
<view wx:for="{{showImgPath}}" wx:key="index">
<image src="{{item.fileID}}"></image>
</view> /**
* 页面的初始数据
*/
data: {
showImgPath: []
},
/**
* 图片上传
*/
onCatchUploadHandler() {
// 1、从本地相册选择图片或使用相机拍照
wx.chooseImage({
count: , //最多选择的图片张数,最大值为9
sizeType: ['original', 'compressed'], //所选图片的尺寸(原图、压缩)
sourceType: ['album', 'camera'], //图片来源(相册、相机),电脑端只会打开相册,而手机端会有两个选项(拍照或者相册)
success(res) {
// tempFilePath可以作为img标签的src属性显示图片
const tempFilePaths = res.tempFilePaths[];
wx.cloud.uploadFile({
cloudPath: new Date().getTime() + 'png', // 上传至云端的路径 可以指定文件夹以及文件名称 如果写死每次上传都会覆盖原有图片
filePath: tempFilePaths, // 小程序临时文件路径
success: res => {
console.log("上传成功")
// 返回文件 ID
db.collection('imgFile')
.add({
data: {
fileID: res.fileID
},
success: (res) => {
console.log(res)
console.log("保存成功")
},
fail: (error) => {
console.log(error)
}
})
},
fail: console.error
})
}
})
},
/**
* 图片展示
*/
onCatchShowHandler() {
// 1、通过云存储查找用户本人管理的图片
wx.cloud.callFunction({
name: 'login',
success: res => {
const openid = res.result.openid;
// 2、去数据库中查找
db.collection('imgFile')
.where({
_openid: openid
})
.get()
.then((res) => {
this.setData({
showImgPath: res.data
})
console.log(res)
})
.catch((error) => {
console.log(error)
})
},
fail: error => {
console.log(error)
}
})
}, - 上传多张图片
- WXML
<!-- 评价 -->
<view class="comment-container">
<van-field value="{{ content }}" placeholder="写一些评价吧" bind:change="onContentChange" />
<van-rate value="{{ score }}" bind:change="onScoreChange" />
<view style="margin-bottom:20rpx">
<van-button type="warning" bindtap="uploadImg" size="small">上传图片</van-button>
</view>
<view>
<image class="comment-img" src="{{item}}" wx:for="{{uploadImages}}" wx:key="index"></image>
</view>
<van-button size="large" type="danger" bindtap="submit">提交评价</van-button>
</view>
</view> - JS
// 对数据库进行初始化
const db = wx.cloud.database(); Page({ /**
* 页面的初始数据
*/
data: {
movieid: '', //对应电影的movieid
movieDetail: {},
content: '', //评价的内容
score: , //电影评分
uploadImages: [], //上传的图片
fileIds: [], //云存储返回的图片id
}, /**
* 生命周期函数--监听页面加载
*/
onLoad: function(options) {
// 获取上一个页面传过来的参数
this.setData({
movieid: options.movieid
})
this.getMovieDetail(options.movieid)
},
/**
* 获取电影详情信息
*/
getMovieDetail(movieid) {
wx.showLoading({
title: '加载中',
})
wx.cloud.callFunction({
name: 'getDetail',
data: {
movieid: movieid
},
success: res => {
this.setData({
movieDetail: JSON.parse(res.result)
})
wx.hideLoading()
},
fail: error => {
console.log(error)
}
})
},
/**
* 输入评价
*/
onContentChange(event) {
this.setData({
content: event.detail //输入框的内容
})
},
/**
* 进行评分
*/
onScoreChange(event) {
this.setData({
score: event.detail
});
},
/**
* 上传图片
*/
uploadImg() {
wx.chooseImage({
count: ,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: res => { //可以改变this指向
// tempFilePath可以作为img标签的src属性显示图片
const tempFilePaths = res.tempFilePaths;
this.setData({
uploadImages: this.data.uploadImages.concat(tempFilePaths)
})
}
})
},
/**
* 提交评价
*/
submit() {
wx.showLoading({
title: '评价中...',
})
// 首先获取到评价的内容 分数 以及上传的图片
// 涉及到了异步(非阻塞)的问题,由于上传时间不确定,因此需要成功上传到云存储才能将fileid存到云数据库
let promiseArr = [];
// 1、上传图片到云存储
for (let i = ; i < this.data.uploadImages.length; i++) {
promiseArr.push(new Promise((resolve, reject) => {
let item = this.data.uploadImages[i];
// 通过正则表达式取出文件对应的扩展名
let suffix = /\.\w+$/.exec(item)[];
wx.cloud.uploadFile({
cloudPath: new Date().getTime() + suffix, // 上传至云端的路径
filePath: item, // 小程序临时文件路径
success: res => {
// 返回文件 ID
this.setData({
fileIds: this.data.fileIds.concat(res.fileID)
});
resolve()
},
fail: console.error
})
}))
}
Promise.all(promiseArr).then((res) => {
// 2、插入数据
db.collection('comment').add({
data: {
content: this.data.content,
score: this.data.score,
movieid: this.data.movieid,
fileIds: this.data.fileIds
},
success: (res) => {
wx.showToast({
title: '评价成功',
});
wx.hideLoading()
},
fail: (error) => {
wx.hideLoading();
wx.showToast({
title: '评价失败',
})
}
}) }).catch((error) => {
console.log(error)
})
}, - 效果图
- WXML
- 上传并展示的代码
- wx.cloud.downloadFile ----- 下载文件
- 步骤示意图
- wx.cloud.downloadFile ----- 下载文件
- 代码
- WXML
<view>云存储</view>
<button catchtap="onCatchUploadHandler">上传图片</button>
<button catchtap="onCatchShowHandler">展示图片</button>
<button catchtap="onCatchSettingAgainHandler">再次调起配置页</button>
<view wx:for="{{showImgPath}}" wx:key="index">
<image src="{{item.fileID}}"></image>
<button catchtap="onCatchDownLoadHandler" data-fileID="{{item.fileID}}">下载图片</button>
</view> - JS
/**
* 图片下载
*/
onCatchDownLoadHandler(event) {
const fileID = event.target.dataset.fileid;
wx.cloud.downloadFile({
fileID: fileID,
success: res => {
wx.showToast({
title: '下载成功',
})
// 保存到手机相册
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success: (res) => {
wx.showToast({
title: '保存成功',
})
},
fail: (error) => {
if (error.errMsg === "saveImageToPhotosAlbum:fail:auth denied" || error.errMsg === "saveImageToPhotosAlbum:fail auth deny" || error.errMsg === "saveImageToPhotosAlbum:fail authorize no response") {
wx.showToast({
title: '用户拒绝了',
});
wx.openSetting({
success: res => {
console.log(res)
if (res.authSetting['scope.writePhotosAlbum']) {
wx.showModal({
title: '提示',
content: '获取权限成功,再次点击图片即可保存',
showCancel: false,
})
} else {
wx.showModal({
title: '提示',
content: '获取权限失败,将无法保存到相册哦~',
showCancel: false,
})
}
},
fail: error => {
console.log(error)
}
})
}
}
})
},
fail: error => {
console.log(error)
}
})
},
/**
* 打开配置
*/
onCatchSettingAgainHandler() {
wx.openSetting({
success: res => {
console.log(res)
},
fail: error => {
console.log(error)
}
})
},
- WXML
- 代码
- wx.cloud.deleteFile ----- 删除文件
- wx.cloud.getTempFileURL ----- 获取临时链接
3、云开发的开通
- 打开微信开发工具,点击云开发 -----> 开通 -----> 确定
- 会出现一个环境配置,每个小程序账号可免费创建两个环境,建议是一、开发环境;二、生产环境;
- 注意:开发工具右上角点击 “详情” -----> 本地设置(调试基础库的版本必须在2.2.3以上,才可以支持云开发)
- 云开发提供了一个可视化的控制台,点击云开发即可出现;
4、遇到的问题
微信小程序开发(二)----- 云开发的更多相关文章
- 微信小程序中使用云开发获取openid
微信小程序获取openid 新建一个微信小程序项目 注意要注册一个自己的小程序账号,并有属于自己的appid 点击云开发按钮,自行填入开发环境名称 打开app.js,找到依赖环境 修改为刚才设置的环境 ...
- 微信小程序--简约风博客小程序(基于云开发 - 全开源)
微信小程序--简约风博客小程序(基于云开发 - 全开源) 项目启动纯属突发奇想,想看看博客小程序,例如wehalo博客小程序,但是感觉自建平台还要浪费自己的服务器算力,还没有访问量,省省吧. 本着白嫖 ...
- 微信小程序版博客——开发汇总总结(附源码)
花了点时间陆陆续续,拼拼凑凑将我的小程序版博客搭建完了,这里做个简单的分享和总结. 整体效果 对于博客来说功能页面不是很多,且有些限制于后端服务(基于ghost博客提供的服务),相关样式可以参考截图或 ...
- 微信小程序购物商城系统开发系列-目录结构
上一篇我们简单介绍了一下微信小程序的IDE(微信小程序购物商城系统开发系列-工具篇),相信大家都已经蠢蠢欲试建立一个自己的小程序,去完成一个独立的商城网站. 先别着急我们一步步来,先尝试下写一个自己的 ...
- 微信小程序购物商城系统开发系列-工具篇
微信小程序开放公测以来,一夜之间在各种技术社区中就火起来啦.对于它 估计大家都不陌生了,对于它未来的价值就不再赘述,简单一句话:可以把小程序简单理解为一个新的操作系统.新的生态,未来大部分应用场景都将 ...
- 微信小程序购物商城系统开发系列
微信小程序购物商城系统开发系列 微信小程序开放公测以来,一夜之间在各种技术社区中就火起来啦.对于它 估计大家都不陌生了,对于它未来的价值就不再赘述,简单一句话:可以把小程序简单理解为一个新的操作系统. ...
- 从微信小程序到鸿蒙js开发【11】——页面路由
目录: 1.router.push()&wx.navigateTo() 2.router.replace()&wx.redirectTo() 3.router.back()&w ...
- 从微信小程序到鸿蒙js开发【12】——storage缓存&自动登录
鸿蒙入门指南,小白速来!从萌新到高手,怎样快速掌握鸿蒙开发?[课程入口] 正文: 在应用开发时,我们常需要将一些数据缓存到本地,以提升用户体验.比如在一个电商的app中,如果希望用户登录成功后,下次打 ...
- 从微信小程序到鸿蒙js开发【13】——list加载更多&回到顶部
鸿蒙入门指南,小白速来!从萌新到高手,怎样快速掌握鸿蒙开发?[课程入口] 目录: 1.list加载更多 2.list回到顶部 3.<从微信小程序到鸿蒙js开发>系列文章合集 1.list加 ...
- 从微信小程序到鸿蒙js开发【15】——JS调用Java
鸿蒙入门指南,小白速来!0基础学习路线分享,高效学习方法,重点答疑解惑--->[课程入口] 目录:1.新建一个Service Ability2.完善代码逻辑3.JS端远程调用4.<从微信小 ...
随机推荐
- mysqli在php7中的使用
mysqli这个库还是比较繁杂的,这其中又分mysqli ,mysqli_stmt,mysqli_result......一堆类,特别乱 这里奉上thinkphp5.1中使用mysqli扩展的查询用法 ...
- 【C#-枚举】枚举的使用
枚举是用户定义的整数类型. namespace ConsoleApplication1 { /// <summary> /// 在枚举中使用一个整数值,来表示一天的阶段 /// 如:Tim ...
- Python 面向对象Ⅳ
类的继承 面向对象的编程带来的主要好处之一是代码的重用,实现这种重用的方法之一是通过继承机制. 通过继承创建的新类称为子类或派生类,被继承的类称为基类.父类或超类. 继承语法 在python中继承中的 ...
- Open Cascade 转化为OpenSceneGraph中的Mesh
#include <osgDB/ReadFile> #include <osgViewer/Viewer> #include <osgGA/StateSetManipul ...
- python re.match与re.search的区别
re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None:而re.search匹配整个字符串,直到找到一个匹配. #!/usr/bin/python impor ...
- C# 写日志的方法
public void WriteLog(string msg) { string filePath = AppDomain.CurrentDomain.BaseD ...
- 分治NTT:我 卷 我 自 己
感觉这种东西每次重推一遍怪麻烦的,就写在这里了. 说白了就是根据分治区间左端点是否为\(0\)分类讨论一下,一般是如果不是\(0\)就要乘\(2\),不过还是需要具体问题具体分析一下才好(就比如下面的 ...
- 实现图像添加label
void CmapwingisTest2View::OnToolsAddTiffLayer() { TCHAR szFilters[]= _T("TIFF Files (*.tif)|*.t ...
- winscp连接后目录名称乱码
1.点击[编辑](点后变为保存按钮)按钮,高级按钮变为可用,点击[高级] 2.文件名utf-8编码,默认为“自动”,勾选为“开启”
- Swagger常用参数用法
别提示:本人博客部分有参考网络其他博客,但均是本人亲手编写过并验证通过.如发现博客有错误,请及时提出以免误导其他人,谢谢!欢迎转载,但记得标明文章出处:http://www.cnblogs.com/m ...