小程序模版
区别于普通的小程序:
- 目录结构 官网模版
- 使用微信开发者工具调试项目,请将项目 整个文件夹 作为运行目录。
project.config.json
中miniprogramRoot
的启动目录设置为client/dist/
cloudfunctionRoot
设置目录为cloud/functions/
- 入口文件
src/app.jsx
添加
componentDidMount() {
wx.cloud.init({
env: "环境ID"
});
}
数据库
云开发提供了一个 JSON 数据库,一个数据库可以有多个集合(相当于关系型数据中的表),集合可看做一个 JSON 数组,数组中的每个对象就是一条记录,记录的格式是 JSON 对象。
建立数据库步骤:
- 小程序内点击云开发 - 数据库
- 新建一个集合(表)
- 对应集合中添加需要的字段,JSON 格式。
- 索引字段默认为
_id
, 使用系统自动生成的 id
云函数的开发和调试
- 建立好云函数文件夹后,打开开发者开发工具,右键云函数文件夹,新建 Node.js 云函数。会自动生成一个文件夹,并且同时部署到远程
文件结构如下
├── sum 云函数名
│ ├── config.json 配置文件
│ ├── package.json 依赖包
│ ├── index.js 云函数主体
- 修改新建的云函数
一开始发现怎么改
index.js
都不起作用,原来是修改后远程的云函数并未自动更新,解决方案:
- 修改后直接上传和部署:每次修改都得重新部署,麻烦
- 云函数本地调试 官网文档
本地调试云函数首先得安装依赖
npm i
,同时监听文件的更改,部署到云端不上传 node_modules
云函数的注意事项和总结
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()
const _ = db.command
exports.main = async (event, context) => {
try {
return await db
.collection('todos')
.where({
_id: _.in(event.ids),
})
.remove()
} catch (e) {
console.error(e)
}
}
- 异步问题:可以使用 generator 语法
- 批量处理多条数据可以使用
where
语句,搭配command
中的方法 node_modules
: 本地调试和部署到云端,前者需要,后者不需要- 调用云函数:
wx.cloud.callFunction
,要根据返回的result
数据判断是是否执行成功,云函数执行失败,返回的数据可能不包含result
字段或者为null
具体实例
获取 oppenid 和 unionid
- 云函数
const cloud = require('wx-server-sdk')
cloud.init()
// 云函数入口函数
exports.main = async (event, context) => {
const wxContext = cloud.getWXContext()
return {
event,
openid: wxContext.OPENID,
appid: wxContext.APPID,
unionid: wxContext.UNIONID,
}
}
获取用户信息
- 云函数
const cloud = require('wx-server-sdk')
cloud.init({})
exports.main = async (event, context) => {
const res = await cloud.getOpenData({
list: [event.cloudID], // CloudID 字符串列表
})
return res.list
}
- 小程序端
<button
type="primary"
openType="getUserInfo"
onGetUserInfo="{this.getUserInfo}"
className="marginTop"
>
获取微信信息
</button>
getUserInfo = function (e) {
wx.cloud.callFunction({
name: 'getUserInfo',
data: {
cloudID: e.detail.cloudID,
},
success: (res) => {
console.log(res)
},
})
}
增
- 云函数
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()
exports.main = async (event, context) => {
const {
description = '',
done = '',
date = new Date(),
tags = [],
title = '',
} = event
try {
// todos 数据库中的表名
const res = await db.collection('todos').add({
// data 字段表示需新增的 JSON 数据
data: {
description,
done,
date,
tags,
title,
},
})
return res
} catch (e) {
console.error(e)
}
}
- 小程序
wx.cloud
.callFunction({
name: 'addTodo',
data: {
description,
done,
date,
tags,
title,
},
})
.then((res) => {
if (res && res.result && res.result._id) {
console.log('success')
} else {
console.log('添加失败')
}
})
删
- 云函数
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()
const _ = db.command
exports.main = async (event, context) => {
try {
// where 删除所有符合条件的id
return await db
.collection('todos')
.where({
_id: _.in(event.ids),
})
.remove()
} catch (e) {
console.error(e)
}
}
- 小程序端调用
wx.cloud
.callFunction({
name: 'delTodo',
data: { ids: this.state.checkedList },
})
.then((res) => {
if (res && res.result && res.result.stats && res.result.stats.removed > 0) {
console.log('delete success')
}
})
改
- 云函数
// 云函数入口函数
exports.main = async (event, context) => {
try {
const {
description = '',
done = '',
date = new Date(),
tags = [],
title = '',
id = '',
} = event
// 根据 id 去修改数据
const res = await db.collection('todos').doc(id).update({
data: {
description,
done,
date,
tags,
title,
},
})
return res
} catch (error) {
console.log(error)
}
}
- 小程序端
类似于增,需要多传一个参数 id
查
- 云函数
云函数每次限制查出 100 条数据,要查出所有的数据,需要循环的去查
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database()
const MAX_LIMIT = 100
exports.main = async (event, context) => {
const _id = event.id
if (_id) {
// 单条查询
const res = await db
.collection('todos')
.where({
_id,
})
.get()
return res
} else {
// 先取出集合记录总数
const countResult = await db.collection('todos').count()
const total = countResult.total
// 计算需分几次取
const batchTimes = Math.ceil(total / 100)
// 承载所有读操作的 promise 的数组
const tasks = []
for (let i = 0; i < batchTimes; i++) {
const promise = db
.collection('todos')
.skip(i * MAX_LIMIT)
.limit(MAX_LIMIT)
.get()
tasks.push(promise)
}
// 等待所有
return (await Promise.all(tasks)).reduce((acc, cur) => ({
data: acc.data.concat(cur.data),
errMsg: acc.errMsg,
}))
}
}
上传文件 - 图片
- 云函数
const cloud = require('wx-server-sdk')
const fs = require('fs')
cloud.init()
exports.main = async (event, context) => {
const fileStream = fs.createReadStream(event.filePath)
return await cloud.uploadFile({
cloudPath: event.cloudPath,
fileContent: fileStream,
})
}
- 小程序端
wx.chooseImage({
count: 2,
sizeType: ['original', 'compressed'],
sourceType: ['album', 'camera'],
success: function (res) {
const filePath = res.tempFilePaths[0]
// 上传图片
var timestamp = Date.parse(new Date())
// test_img/ 文件夹路径
const cloudPath = 'test_img/' + timestamp + filePath.match(/\.[^.]+?$/)[0]
wx.cloud.uploadFile({
cloudPath,
filePath,
success: (data) => {
console.log(data)
},
fail: () => {
console.log('faile')
},
complete: () => {
console.log('complete')
},
})
},
fail: (e) => {
console.error(e)
},
})