小程序云开发 问题指南
最近在搞小程序的比赛,咋就是说浅记录一下学习小程序开发途中踩过的坑,遇到的让人高血压的问题,另外本文档是本人在b站学习新视觉课程所记录的,大家有需要可以去b站看看。
云开发 数据库
数据库链接
1.数据库链接时用自己的环境
在开始使用数据库 API 进行增删改查操作之前,需要先获取数据库的引用。以下调用获取默认环境的数据库的引用:
const db = wx.cloud.database()
如需获取其他环境的数据库引用,可以在调用时传入一个对象参数,在其中通过 env 字段指定要使用的环境。此时方法会返回一个对测试环境数据库的引用。
示例:假设有一个环境名为 test,用做测试环境,那么可以如下获取测试环境数据库:
const testDB = wx.cloud.database({
env: 'test'//注意使用时加上环境id
})
// eg
const db = wx.cloud.database({
env: 'bruan-cloud-8gr3l2csc1'
})
数据库传值setData
1.普通表达式传值传不进去的问题
//注意应该使用箭头表达式 普通表达式虽然可以查询但无法
//使用this.setData{}进行传值
db.collection('todos').doc('todo-identifiant-aleatoire').get({
success: function(res) {
// res.data 包含该记录的数据
console.log(res.data)
}
}
//修正
success: res => {
// res.data 包含该记录的数据
console.log(res.data);
this.setData({
DataList:res.data;
})
}
2. then()与回调地狱的问题
使用then()可以有效避免回调地狱
then相当于succee:
db.collection('todos').doc('todo-identifiant-aleatoire').get().then(res => {
// res.data 包含该记录的数据
console.log(res.data)
})
数据库查询
1.使用where查询
where 加上字段名称 赋值
getData(){
db.collection("demolist").where({
author:"曾运镖"
}).get()
.then(res=>{
console.log(res);
})
},
数据库插入
1.插入数据
<button type="primary" bindtap="addData">插入一条数据</button>
db.collection('todos').add({
// data 字段表示需新增的 JSON 数据
data: {
description: "learn cloud database",
due: new Date("2018-09-01"),
tags: [
"cloud",
"database"
],
location: new db.Geo.Point(113, 23),
done: false
}
})
.then(res => {
console.log(res)
})
2.提交表单到云数据库
<form bindsubmit="btnSub">
<input type="text" placeholder="请输入标题" name="title"/>
<input type="text" placeholder="请输入作者" name="author"/>
<textarea name="content" placeholder="请输入内容"></textarea>
<button type="primary" form-type="submit">提交</button>
<button type="warn" form-type="reset">重置</button>
</form>
//提交表单,添加进入数据库
btnSub(res){
console.log(res)
},
Es6的解构赋值,上代码
btnSub(res){
//var title = res.detail.value.title;
//var author = res.detail.value.author;
//var content = res.detail.value.content;
//equal to Es6的解构赋值
var {title,author,content}=res.detail.value;
console.log(title,author,content);
//开始写入数据库
db.collection("demolist").add({
//res.detail.value 是一个对象,故下可以简化为---data:res.detail.value---
data:{
title:title,
author:author,
content:content,
}
}).then(res=>{console.log(res)})
},
修改云数据库数据
1.更新数据方法doc
<button type="primary" bindtap="updateData">更新一条记录</button>
//连接数据库
const db = wx.cloud.database({
env: 'bruan-cloud-8gr3l2cscac'
})
// 更新数据 doc id
// 这里只有添加了openid的字段记录才能更新,一般用户创建的数据才有openid
updateData(){
db.collection("demolist").doc("41ae62ef620cac3f0676ee2b6b06ce5e").update({
data:{
author:"蔡徐坤"
}
}).then(res=>{console.log(res);})
},
#####2.更新方法where
// 更新数据
// 这里只有添加了openid的字段记录才能更新,一般用户创建的数据才有openid
updateData(){
db.collection("demolist").where({
author:"川宝"
}).update({
data:{
author:"蔡徐坤"
//添加从未有过的数据项
posttime:"2020-12-12"
}
}).then(res=>{console.log(res);})
},
3 set 修改数据
等同于update,但只会保存指定项,未提及的会被删
云数据库 删除数据
1.删除数据记录
// 删除数据
delData(){
db.collection("demolist").doc("41ae62ef620ccce00688aa0466099ecb").remove().then(res=>console.log(res));
},
2.表单数据收集
感觉跟用form包裹起来收集表单是一样的
myIpt(res){
//console.log(res);
var vlu = res.detail.value;
console.log(vlu);
},
如何将数据传到__删除响应函数__:使用this.setData({}) 或者定义一个全局变量
3.count个数与watch数据监听
count个数
btnNum(){
db.collection("demolist").count().then(res=>{console.log(res.total);})
}
数据监听
//获取数据
getData(){
db.collection("demolist")
.get()
.then(res=>{
this.setData({
dataArr:res.data
})
})
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getData();
db.collection("demolist").watch({
onChange:res=>{
//将修改后返回的数据重新覆盖到dataArr
console.log(res.docs)
this.setData({
dataArr:res.docs
})
},
onError:res=>{
console.log(res)
}
})
各项构建查询条件
//limit限制结果集个数 orderby 按项排序 skip(3)跳过3条记录
getData(){
db.collection("demolist").limit(3).skip(3).orderBy("time","asc").get().then(
res=>{console.log(res)}
)
},
格式化返回对象用field() 相当于MySQL的select()
getData(){
db.collection("demolist").field({
title:true,
author:true
}).get().then(
res=>{console.log(res)}
)
},
command
1.command的介绍
官方文档:Command.and(expressions: any[]): Command | 微信开放文档 (qq.com)
const _ = db.command;
getData(){
db.collection("demolist").where({
hits:_.eq(543)
})
.get()
.then(res=>{console.log(res)
this.setData({
dataList:res.data
})
})
},
2.and or关系,直接查询返回结果,只带一个对象hist…
getData(){
db.collection("demolist").where({
hits:_.and(_.gt(0),_.lt(100))
})
.get()
.then(res=>{console.log(res)
this.setData({
dataList:res.data
})
})
},
//默认关系为and
getData(){
db.collection("demolist").where({
hits:_.gt(0)
hits:_.lt(100)
})
.get()
.then(res=>{console.log(res)
this.setData({
dataList:res.data
})
})
},
//也可以使用不同的对象,但是这样写只有and关系,要用or应该用[]
getData(){
db.collection("demolist").where({
hits:_.gt(0)
author:"曾运镖"
})
.get()
.then(res=>{console.log(res)
this.setData({
dataList:res.data
})
})
},
3.or and 关系且带多个对象,如hits author…
要用[]包住语句
getData(){
db.collection("demolist").where(
_.or([
{
hits:_.lt(300)
},{
author:_.eq("曾运镖")
}
])
)
.get()
.then(res=>{console.log(res)
this.setData({
dataList:res.data
})
})
},
db.collection("demolist").where(
_.and([
{
hits:_.lt(300)
},{
author:_.eq("曾运镖")
}
])
)
.get()
.then(res=>{console.log(res)
this.setData({
dataList:res.data
})
})
},
4. command数组操作符
//找出tags中为cloud database的记录
const _ = db.command
db.collection('todos').where({
tags: _.all(['cloud', 'database'])
})
.get({
success: console.log,
fail: console.error
})
//找出 tags 数组字段长度为 2 的所有记录
const _ = db.command
db.collection('todos').where({
places: _.size(2)
})
.get({
success: console.log,
fail: console.error,
})
5更新字段与数组
b不用获取数据直接调用inc()实现,点击量自增(或者自减)
被修改的数据应该为数字类型
update(){
db.collection("demolist").doc("617ef50c620d2b9406489dcd1190f03e").update({
data:{
hits:_.inc(1)
}
}).then(res=>console.log(res))
},
set对象
// 以下方法只会更新 style.color 为 red,而不是将 style 更新为 { color: 'red' },即不影响 style 中的其他字段
db.collection('todos').doc('doc-id').update({
data: {
style: {
color: 'red'
}
}
})
// 以下方法更新 style 为 { color: 'red', size: 'large' }
db.collection('todos').doc('doc-id').update({
data: {
style: _.set({
color: 'red',
size: 'large'
})
}
})
数组操作
示例 1:尾部添加元素
const _ = db.command
db.collection('todos').doc('doc-id').update({
data: {
tags: _.push(['mini-program', 'cloud'])
}
})
示例 2:从第二个位置开始插入
const _ = db.command
db.collection('todos').doc('doc-id').update({
data: {
tags: _.push({
each: ['mini-program', 'cloud'],
position: 1,
})
}
})
示例 3:排序
插入后对整个数组做排序
const _ = db.command
db.collection('todos').doc('doc-id').update({
data: {
tags: _.push({
each: ['mini-program', 'cloud'],
sort: 1,
})
}
})
不插入,只对数组做排序
const _ = db.command
db.collection('todos').doc('doc-id').update({
data: {
tags: _.push({
each: [],
sort: 1,
})
}
})
如果字段是对象数组,可以如下根据元素对象里的字段进行排序:
const _ = db.command
db.collection('todos').doc('doc-id').update({
data: {
tags: _.push({
each: [
{ name: 'miniprogram', weight: 8 },
{ name: 'cloud', weight: 6 },
],
sort: {
weight: 1,
},
})
}
})
示例 4:截断保留
插入后只保留后 2 个元素
const _ = db.command
db.collection('todos').doc('doc-id').update({
data: {
tags: _.push({
each: ['mini-program', 'cloud'],
slice: -2,
})
}
})
示例 5:在指定位置插入、然后排序、最后只保留前 2 个元素
const _ = db.command
db.collection('todos').doc('doc-id').update({
data: {
tags: _.push({
each: ['mini-program', 'cloud'],
position: 1,
slice: 2,
sort: 1,
})
}
})
云函数
配置 出现找不到对应的FunctionName
云函数第一次使用时需要配置云端环境,还有本地需要安装JavaScript环境。
1.第一次上传部署云函数,建议先安装一下node.js。
https://nodejs.org/en/ 下载nodejs,然后直接安装,在cmd控制台输入node -v和npm -v,这两个打印版本号的命令可以判断node和npm是否安装成功,记得检查路径有没有配好,装nodejs配完路径后记得重启小程序ide,是一整个退出再进入
2.这时可以进行第一次上传部署云函数的操作了,如果你已经执行过了,那现在就需要手工来安装wx-server-sdk依赖了。
3.右击新建的云函数文件夹,会有“在终端打开”选项,点击,就会进入命令行界面,先查下npm的版本,看看有没有安装npm,没有安装要先安装,安装好的,就直接运行命令:npm install --save wx-server-sdk@latest
4.安装成功后,云函数文件夹下面会多个package-lock.json文件,就对了。
现在重新上传部署一下云函数,就可以使用云函数啦。如果还是不行,那就需要在调用的函数那里加上config:{env:“bruan-cloud-8gr3l2csc1d(这里是环境id)”},
还有一个很重要的原因,网络不通也会导致云函数上传出现问题,这需要登录云开发后台删除对应云函数在重新上传
error message wx is not defined; at cloud.callFunction api;
在服务端获取数据库不需要wx命名空间,云函数上const db = wx.cloud.database这一句把wx.去掉,官方文档里分为小程序端和服务端,有区别的
可以返回对象但得不到数据
右键云函数,可能是没有进行上传,点击上传并部署,云端安装依赖
云函数调用代码
getData云函数
index.js
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database({
env: "bruan-cloud-8gr3l2csc1dd6dac"
});
// 云函数入口函数
exports.main = async (event, context) => {
return await db.collection("demolist").get()
}
demo4.js
Page({
/**
* 页面的初始数据
*/
data: {
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
wx.cloud.callFunction({
//很关键
config:{ env: 'bruan-cloud-8gr3l2csc1dd6dac' },
name:"getData",
//data:{},
}).then(res=>console.log(res))
},
与云函数进行数据传递
将数据写在data里面,以达到传递的效果
onLoad: function (options) {
wx.cloud.callFunction({
config:{ env: 'bruan-cloud-8gr3l2csc1dd6dac' },
name:"getData",
data:{
name:"连宝",
age:"15",
},
}).then(res=>console.log(res))
},
exports.main = async (event, context) => {
var name = event.name;
var age = event.age;
return name;
//return event;
}
案例之滑动数据加载
//demo5.js
/**
* 页面的初始数据
*/
data: {
dataList:[]
},
getData(num=5,page=0){
wx.cloud.callFunction({
config:{env:"bruan-cloud-8gr3l2csc1dd6dac"},
name:"demolistget",
data:{
num:num,
page:page,
}
})
.then(res=>{
//新旧数据链接
var oldData=this.data.dataList;
var newData= oldData.concat(res.result.data);
console.log(res);
this.setData({
dataList:newData
})
})
},
/**
* 页面上拉触底事件的处理函数
*/
onReachBottom: function () {
//page页面更换
var page = this.data.dataList.length
this.getData(5,page);
},
/**
* 生命周期函数--监听页面加载
*/
onLoad: function (options) {
this.getData(4,0);
},
//demolistget----index.js
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database({
env:"bruan-cloud-8gr3l2csc1dd6dac",
});
// 云函数入口函数
exports.main = async (event, context) => {
var num = event.num;
var page = event.page;
return await db.collection("demolist").skip(page).limit(num).get()
}
<view class="row" wx:for="{{dataList}}" wx:key="index">
<view class="title">{{index+1}}、{{item.title}}</view>
<view>阅读量:{{item.hits}}</view>
</view>
案例之获取点击量
//demoupdate----index.js
// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init()
const db = cloud.database({
env: 'bruan-cloud-8gr3l2csc1dd6dac'
});
const _ = db.command;
// 云函数入口函数
exports.main = async (event, context) => {
//传入id
var id = event.id;
console.log("调用了云函数");
return await db.collection("demolist").doc(id).update({
data:{
hits:_.inc(13),
}
})
}
//点击量函数
clickRow(res){
wx.showLoading({
title: '数据加载中...',
})
//1.获取id 索引值
// 2.云函数更新
// 3.前后端链接
// 4.重新渲染列表
console.log(res.currentTarget.dataset);
var {id,idx}=res.currentTarget.dataset;
wx.cloud.callFunction({
config:{ env: 'bruan-cloud-8gr3l2csc1dd6dac' },
name:"demoupdate",
data:{
id:id
}
}).then(res=>{
var newData=this.data.dataList
//设置渲染点击量 前端内容 与数据库无关
newData[idx].hits+=13;
this.setData({
dataList:newData
})
})
wx.hideLoading();
},
云存储
上传文件
上传文件时要注意上传时指定环境id
API upload 链接
clickBtn(){
wx.chooseImage({
success:res=>{
console.log(res)
var filePath = res.tempFilePaths[0]
this.cloudFile(filePath)
}
})
// wx.cloud.uploadFile({
// cloudPath:"demopic/123.jpg",
// filePath:"临时路径",
// })
},
cloudFile(path){
wx.cloud.uploadFile({
//手动指定环境位置
config:{ env: 'bruan-cloud-8gr3l2csc1dd6dac' },
cloudPath:Date.now()+".jpg",
filePath:path,
}).then(res=>{console.log(res)})
},
一次性上传多个文件
<button type="primary" bindtap="clickBtn">上传文件</button>
<image wx:for="{{urlArr}}" src="{{item}}"></image>
// pages/demo6/demo6.js
// 这是在最外面的定义
var urlArr=[];
var filePath=[];
Page({
/**
* 页面的初始数据
*/
data: {
},
//按钮事件
clickBtn(){
wx.chooseImage({
success:res=>{
//var filePath = res.tempFilePaths[0]
filePath=res.tempFilePaths;
filePath.forEach((item,index)=>{
var filename=Date.now()+"_"+index;
this.cloudFile(filename,item);
})
}
})
},
//上传事件封装
cloudFile(filename,path){
wx.showLoading({
title: '上传中...',
})
wx.cloud.uploadFile({
config:{ env: 'bruan-cloud-8gr3l2csc1dd6dac' },
cloudPath:filename+".jpg",
filePath:path,
}).then(res=>{
console.log(res)
urlArr.push(res.fileID)
//判断是否达到核定容量,达到后再一次性进行渲染
if(filePath.length==urlArr.length){
this.setData({
urlArr:urlArr,
})
}
})
wx.hideLoading({})
},