
传统开发需要考虑
- 成本角度:维护服务器成本,并且需要考虑并发量大之后的服务器的扩展;
- 技术研发:对于单纯会前端的人来说,学习后端相关技术成本较高
1、云数据库
2、云存储
3、云函数
新建小程序项目,填入 AppID 并 勾选微信云开发,点击确认即可

如图,创建了具有云开发基础能力的小程序;其中 cloudfunctions 目录下放云函数代码,miniprogram 目录下放小程序代码

点击开发者工具中的云开发,开通即可

1、什么是环境
2、什么是配额
在小程序端开始使用云能力前,需要调用 wx.cloud.init 方法完成云能力的初始化
| 字段 | 数据类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| env | string | object | 是 | 默认选中环境 | 后续 API 调用的默认环境配置,传入字符串形式的环境 ID 可以指定所有服务的默认环境 |
| traceUser | boolean | 否 | false | 是否在将用户访问记录到用户管理中,在控制台中可见 |
步骤一:在 miniprogram -> app.js 中 进行云能力的初始化
// app.js
App({
onLaunch: function () {
wx.cloud.init({
// env 参数说明:
// env 参数决定接下来小程序发起的云开发调用(wx.cloud.xxx)会默认请求到哪个云环境的资源
// 此处请填入环境 ID, 环境 ID 可打开云控制台查看
// 如不填则使用默认环境(第一个创建的环境)
env: 'my-env-id',
traceUser: true,
});
}
});
步骤二:你可以在 project.config.json (在根目录) 文件中,指定自定义目录作为云开发的本地根目录,和小程序端目录,一般用默认
示例:
{
"miniprogramRoot": "miniprogram/",
"cloudfunctionRoot": "cloudfunctions/",
}
关系型数据库和 文档型数据库的概念对应关系如下表:
| 关系型 | 文档型 |
|---|---|
| 数据库 database | 数据库 database |
| 表 table | 集合 collection |
| 行 row | 记录 record / doc |
| 列 column | 字段 field |
能在云开发控制台中,可视化的操作(增删改查)数据库

添加数据的调用过程
【示例:在小程序端某页面上点击某按钮往集合中添加数据】
Page({
// 点击按钮的事件监听
onInsertDataTap() {
// 1. 获取数据库
const db = wx.cloud.database();
// 2. 通过数据库获取 users集合; 注:users 是已创建的集合的名称
const collection = db.collection('users');
// 2. 在该集合中添加数据 ,调用add方法
collection.add({
// data 字段表示需新增的 JSON 数据
data: {
name: 'jack',
age: 16,
bobbies: ['篮球', '足球'],
address: {
"city": "北京",
"postcode": 111111
}
},
// 添加成功的回调
success: function (res) {
// res 是一个对象,其中有 _id 字段标记刚创建的记录的 id
console.log(res)
}
})
}
});
获取操作后的回调结果可选用风格有:
修改数据有两种方式
Page({
onUpdateDataTap() {
const db = wx.cloud.database();
const collection = db.collection('users');
// 1. update方法;更改局部字段
// doc方法用于根据传入 _id 字段的值 (这个字段是记录的唯一标识) 查询到某条记录
collection.doc('b17ee42c6382cd5101206fd657058e8f').update({
// data 传入需要局部更新的数据
data: {
name: 'lucy', // 即只更新name字段 为lucy
},
})
// 2. set 方法 ;更改整条记录
collection.doc('b17ee42c6382cd5101206fd657058e8f').set({
data: {
// 将整个记录替换为只有一个字段为name的记录(_id,_oppenid除外);
name: 'lucy',
},
})
}
});
对记录使用 remove 方法可以删除该条记录
db.collection('users').doc('b17ee42c6382cd5101206fd657058e8f').remove({
success: function(res) {
console.log('删除成功' + res)
}
})
如果需要更新多个数据,可通过 where 语句选取多条记录执行删除,只有有权限删除的记录会被删除
db.collection('users').where().remove({
success: function(res) {
console.log('删除成功' + res)
}
})
1、查询数据的方式
db.command 的 指令2、查询指令
db.command 对象上。| 查询指令 | 说明 |
|---|---|
| eq | 等于 |
| neq | 不等于 |
| lt | 小于 |
| lte | 小于或等于 |
| gt | 大于 |
| get | 大于或等于 |
| in | 字段值在给你的那个数组中 |
| nin | 字段值不在给定数组中 |
【示例】
const db = wx.cloud.database();
const collection = db.collection('users');
//
// 1. 精准查询
collection.doc('1caddbb26382dcb000fc7a5e01df0893').get().then(res => {
console.log(res.data) // promise 风格
})
// 2. 根据条件查询
collection.where({
age: 20, // age 的 值为 20 的记录
}).get({
success: function (res) {
console.log(res) // 回调风格
}
})
// 3. 根据查询指令
const _ = db.command; // 获取 查询指令
collection.where({
age: _.gt(20)
}).get().then(res => {
console.log(res.data);
})
// 4. 正则表达式查询
collection.where({
name: db.RegExp({
regexp: 'u', // name字段 包含 u 的 记录
options: 'i' // i 不区分大小写
})
}).get().then(res => {
console.log(res.data)
})
// 5. 获取整个集合的记录
collection.get().then(res => {
console.log(res.data); // 会有数量限制
})
// 6. 综合查询
collection.field({
name:true, // 只查询显示 name 和 age 字段,不显示其他字段
age:true
}).skip(2).limit(3).orderBy('cardId','asc').get().then(res=>{
// skip 跳过两条记录;limit 限制查询的数量;orderBy 指定查询排序条件
console.log(res.data)
})
云存储用于将文件存储到云端:
云存储常见的操作:
云存储可视化面板

// onUpLoadFileTap 为点击按钮触发的上传事件
async onUpLoadFileTap() {
// 1. 从本地选择一个图片
const res = await wx.chooseMedia({
mediaType: 'image'
})
const filePath = res.tempFiles[0].tempFilePath;
// 2. 拼接图片的名称
const timestamp = new Date().getTime(); // 用时间戳命名文件,避免文件名冲突
const openid = 'xxxid'; // 这里假设获取了用户的openid;也作为文件名一部分
const extension = filePath.split('.').pop(); // 获取最后的文件扩展名
const fileName = `${timestamp}_${openid}.${extension}`;
// 3. 上传文件
const result = await wx.cloud.uploadFile({
filePath,
cloudPath: 'images/' + fileName // 存到云端 images 下
})
console.log(result);
}
fileID 在小程序端直接访问async onGetTempURLTap() {
const res = await wx.cloud.getTempFileURL({
fileList: ['cloud://cloud1-3gdazm984a860482.636c-cloud1-3gdazm984a860482-1314762551/images/1669531216039_xxxid.png']
})
console.log(res); // res对象中含fileList数组,其中元素有 tempFileURL 属性
}
如果文件放在云存储中,希望把文件下载到本地使用,就可以使用云存储的文件下载了
async onDownloudTap() {
const res = await wx.cloud.downloadFile({
fileID: 'cloud://cloud1-3gdazm984a860482.636c-cloud1-3gdazm984a860482-1314762551/images/1669531216039_xxxid.png'
})
console.log(res.tempFilePath); // 拿到tempFilePath
}
从云存储删除不需要的文件,可以节省空间
async onDeleteFileTap() {
// 删除文件
const res = await wx.cloud.deleteFile({
fileList: ["cloud://cloud1-3gdazm984a860482.636c-c loud1-3gdazm984a860482-1314762551/images/1669531216039_xxxid.png"]
})
console.log(res);
}
云函数即在云端(服务器端)运行的函数。
云函数的编写方式
云开发的云函数的独特优势在于与微信登录鉴权的无缝整合


// 小程序端代码
Page({
// 点击按钮的事件监听
async onSumTap() {
const res = await wx.cloud.callFunction({
name: 'sum', // 云函数名
data: { // data为传给云函数的参数
num1: 2,
num2: 3
}
})
console.log(res.result);
},
})
// 云函数端
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
}) // 使用当前云环境
// 云函数入口函数
exports.main = async (event, context) => {
// event 对象 为 小程序端 调用云函数传入的参数
return event.num1 + event.num2
}
wx-server-sdk 提供的 getWXContext 方法获取到每次调用的上下文(appid、openid 等)// 云函数入口文件
// index.js
const cloud = require('wx-server-sdk')
exports.main = async (event, context) => {
// 这里获取到的 openId、 appId 和 unionId 是可信的,注意 unionId 仅在满足 unionId 获取条件时返回
let { OPENID, APPID, UNIONID } = cloud.getWXContext()
return {
OPENID,
APPID,
UNIONID,
}
}
云函数中对数据库的操作显示更少,所有通常会再云函数中进行数据库的操作
【示例: 删除users集合中 age 字段大于 20 的记录】
// 云函数端
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
}) // 使用当前云环境
// 云函数入口函数
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()
const db = cloud.database();
const collection = db.collection('users');
const _ = db.command;
const res = await collection.where({
age: _.gt(20)
}).remove()
console.log(res);
return {
res
}
}
// 小程序端
Page({
// onDeleteTap 为 按钮的事件监听回调
async onDeleteTap() {
const res = await wx.cloud.callFunction({
name: 'delete', // 云函数名
})
console.log(res.result);
},
})
云函数中支持对其他服务器进行http请求,也支持使用axios库发送网络请求
// 云函数入口文件
// 现在云函数中下载axios
const axios = require('axios')
const cloud = require('wx-server-sdk')
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
}) // 使用当前云环境
// 云函数入口函数
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()
const res = await axios.get('http://localhost:3000/playlist/detail?id=7770073184')
return {
res
}
}
注意:我在下载axios(1.2.0版本)时后,用
require('axios')导入云函数运行后报错,看报错信息大概是axios不支持require导入的意思,下载低版本如(0.27.2即可)
对于小程序某些域名的限制无法配置时,可以通过云函数作为代理来请求数据,在返回给小程序端
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init({
env: cloud.DYNAMIC_CURRENT_ENV
}) // 使用当前云环境
// 云函数入口函数
exports.main = async (event, context) => {
// 1. 生成小程序码
const QRCodeRes = await cloud.openapi.wxacode.createQRCode({
width: 320, // 二维码的宽度
path: 'page/index/index', // 扫码进入的小程序页面路径
})
// 2. 获取到数据,并上传到云存储中
const wxContext = cloud.getWXContext(); // 获取微信上下文
const timestamp = new Date().getTime();
const openid = wxContext.OPENID; // 获取openid
const extension = QRCodeRes.contentType.split("/").pop(); // 获取后缀名
// 上面4个主要是为了定义文件名,可以自己简单写
const cloudPath = `${timestamp}_${openid}.${extension}`
// 上传到云存储
const uploadRes = await cloud.uploadFile({
fileContent: QRCodeRes.buffer, // 文件内容
cloudPath: cloudPath // 上传到云存储的路径
})
return uploadRes
}
Page({
data: {
QRCodeUrl: '',
},
async getMiniQRcode() {
const res = await wx.cloud.callFunction({
name: "getQRcode"
})
console.log(res);
this.setData({
QRCodeUrl: res.result.fileID // 这里就获取了云存储中的二维码url,可展示在页面
})
}
})
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
前言一般来说,前端根据后台返回code码展示对应内容只需要在前台判断code值展示对应的内容即可,但要是匹配的code码比较多或者多个页面用到时,为了便于后期维护,后台就会使用字典表让前端匹配,下面我将在微信小程序中通过wxs的方法实现这个操作。为什么要使用wxs?{{method(a,b)}}可以看到,上述代码是一个调用方法传值的操作,在vue中很常见,多用于数据之间的转换,但由于微信小程序诸多限制的原因,你并不能优雅的这样操作,可能有人会说,为什么不用if判断实现呢?但是if判断的局限性在于如果存在数据量过大时,大量重复性操作和if判断会让你的代码显得异常冗余。wxswxs相当于是一个独立
项目介绍随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱小学生兴趣延时班预约小程序的设计与开发被用户普遍使用,为方便用户能够可以随时进行小学生兴趣延时班预约小程序的设计与开发的数据信息管理,特开发了小程序的设计与开发的管理系统。小学生兴趣延时班预约小程序的设计与开发的开发利用现有的成熟技术参考,以源代码为模板,分析功能调整与小学生兴趣延时班预约小程序的设计与开发的实际需求相结合,讨论了小学生兴趣延时班预约小程序的设计与开发的使用。开发环境开发说明:前端使用微信微信小程序开发工具:后端使用ssm:VU
@作者:SYFStrive @博客首页:HomePage📜:微信小程序📌:个人社区(欢迎大佬们加入)👉:社区链接🔗📌:觉得文章不错可以点点关注👉:专栏连接🔗💃:感谢支持,学累了可以先看小段由小胖给大家带来的街舞👉微信小程序(🔥)目录自定义组件-behaviors 1、什么是behaviors 2、behaviors的工作方式 3、创建behavior 4、导入并使用behavior 5、behavior中所有可用的节点 6、同名字段的覆盖和组合规则总结最后自定义组件-behaviors 1、什么是behaviorsbehaviors是小程序中,用于实现
我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or
如何学习ruby的正则表达式?(对于假人) 最佳答案 http://www.rubular.com/在Ruby中使用正则表达式时是一个很棒的工具,因为它可以立即将结果可视化。 关于ruby-我如何学习ruby的正则表达式?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1881231/
深度学习12.CNN经典网络VGG16一、简介1.VGG来源2.VGG分类3.不同模型的参数数量4.3x3卷积核的好处5.关于学习率调度6.批归一化二、VGG16层分析1.层划分2.参数展开过程图解3.参数传递示例4.VGG16各层参数数量三、代码分析1.VGG16模型定义2.训练3.测试一、简介1.VGG来源VGG(VisualGeometryGroup)是一个视觉几何组在2014年提出的深度卷积神经网络架构。VGG在2014年ImageNet图像分类竞赛亚军,定位竞赛冠军;VGG网络采用连续的小卷积核(3x3)和池化层构建深度神经网络,网络深度可以达到16层或19层,其中VGG16和VGG
文章目录1、自相关函数ACF2、偏自相关函数PACF3、ARIMA(p,d,q)的阶数判断4、代码实现1、引入所需依赖2、数据读取与处理3、一阶差分与绘图4、ACF5、PACF1、自相关函数ACF自相关函数反映了同一序列在不同时序的取值之间的相关性。公式:ACF(k)=ρk=Cov(yt,yt−k)Var(yt)ACF(k)=\rho_{k}=\frac{Cov(y_{t},y_{t-k})}{Var(y_{t})}ACF(k)=ρk=Var(yt)Cov(yt,yt−k)其中分子用于求协方差矩阵,分母用于计算样本方差。求出的ACF值为[-1,1]。但对于一个平稳的AR模型,求出其滞