微信小程序 之 云开发

一、概念

1. 传统开发模式

2. 新开发模式 ( 云开发模式 )

3. 传统、云开发的模式对比

4. 传统、云开发的项目流程对比

5. 云开发的定位

1. 个人的项目或者想法,不想开发服务器,直接使用云开发
2. 某些公司的小程序项目是使用云开发的,但是不多,大部分还是用自己的服务器
3. 可以让我们了解一些云开发的思想,比如服务器、数据库、存储,有利于之后学习服务器相关知识

6. 云开发核心技术

云开发主要包含三大核心技术 : 云数据库、云存储、云函数

云数据库

  • 提供在小程序端直接对数据库进行增删改查的能力

  • 数据库是类似于MongoDB的文档存储的数据库,操作非常方便

  • 非常简单,不是关系数据库,可以直接往里面存储JSON对象

云存储

  • 可以在小程序端直接上传、下载、删除文件

  • 自带CDN,提高文件访问速度

  • 可以获取临时链接,支持在小程序外访问

云函数

  • 提供了在服务器代码的执行能力

  • 包含微信天然的私有鉴权

  • 更大权限的操作数据库等

  • 进行云调用、HTTP请求等操作

二、创建云开发项目

1. 创建项目

2. 了解云开发

01 - 打开云开发

02 - 创建云开发环境

  • 新建新环境

  • 设置 – 环境名称 – 创建环境

03 - 云开发控制台

  • 运营分析

  • 数据库(云数据库)

  • 存储(云存储)

  • 云函数

04 - 环境与配额

环境
  • 一个环境对应一整套独立的云开发资源,包括数据库、存储空间、云函数等资源

  • 各个环境是相互独立的,用户开通云开发后即创建了一个环境,默认可拥有最多两个环境

  • 在实际开发中,建议多配备几个环境

  • 测试环境

  • 预发环境

  • 线上环境

配额
  • 可以根据自己的业务量选择对应的更高配额

3. 云开发项目初始化

在小程序端开始使用云能力前,需先调用 wx.cloud.init 方法完成云能力初始化

01 - 在app.js 中初始化

// app.js
App({
  onLaunch: function () {
    // 1. 判断是否有云开发能力
    if (!wx.cloud) {
      console.error('请使用 2.2.3 或以上的基础库以使用云能力');
    } else {
      // 2. 初始化云开发
      wx.cloud.init({
        /**
         * env
         * env 参数决定接下来小程序发起的云开发调用(wx.cloud.xxx)会默认请求到哪个云环境的资源
         * 此处请填入环境 ID, 环境 ID 可打开云控制台查看
         */
        env: 'my-env-id',
        /**
         * traceUser
         * 是否要跟踪用户
         * 打开后,可在 云开发控制台 - 运营分析 - 用户访问,观看到访问列表
         */
        traceUser: true,
      });
    }
    this.globalData = {};
  }
});

02 - 路径可进行配置

三、云数据库

1. 概念

网址 : 微信开发文档 - 云数据库

数据库介绍

  • JSON数据库

  • 云开发提供了一个文档型数据库,类似于MongoDB,里面存放的是一条条JSON格式的对象

  • 一个数据库可以包含多个集合,一个集合中包含多个JSON对象

  • 提供方便的API调用:学习这些API即可

  • 提供了小程序端和服务器端(云函数)中调用的区分

数据库集合的权限

若想每个人都 可读 可写

2. 操作数据库 – 控制台操作

01 - 打开

02 - 创建集合

相当于是一个数组 []

03 - 创建一条数据 ( 记录 )

相当于是数组 [] 中的一条数据

默认模式

JSON模式

04 - 导入数据

3. 操作数据库 - 代码操作

// 1. 获取数据库对象
const db = wx.cloud.database()
// 2. 获取操作的集合
const stuCollect = db.collection('students')

增加数据

在数据库中刷新即可看到新增加的数据
ps : 代码添加的数据,_openid字段也会新增上,作为唯一标识
  • 获取操作后的回调结果

  • 基于回调:传入success、fail、complete

  • 基于Promise:使用then、catch、finally

添加单条数据

// 1. 获取对应的数据库
const db = wx.cloud.database()
// 2. 获取到要操作的集合 (collection)
const stuCollect = db.collection('students')

Page({
  // 新增数据
  addData() {
    stuCollect.add({
      // 数据
      data: {
        name: '小王',
        age: 20,
        hobbies: ['bvvv'],
        address: {
          alias: 'HB',
          name: '湖北',
          code: '333343'
        }
      },
      // 可以使用回调函数
      success: ({ errMsg }) => {
        if (errMsg === 'collection.add:ok') {
          wx.showToast({
            title: '添加成功',
          })
        }
      }
    })
    // // 也可以使用promise
    // .then((res) => { console.log(res) })
  }
})

循环添加数据

// 1. 获取数据库对象
const db = wx.cloud.database()
// 2. 获取操作的集合
const yzCollect = db.collection('YZ')

Page({
  // 增加数据
  onAdd() {
    // 请求10页的数据
    for (let i = 1; i <= 10; i++) {
      wx.request({
        // 测试用途 : 抓取下某鱼的数据
        url: 'https://m.douyu.com/api/room/list',
        data: {
          page: i,
          type: 'yz'
        },
        success: (res) => {
          const list = res.data.data.list
          this.addData(list)
        }
      })
    }
  },
  addData(list) {
    list.forEach(item => {
      // 循环添加数据
      yzCollect.add({
        data: item
      }).then(() => {
        console.log(`${item.roomName}:添加成功`);
      })
    })
  },
})

删除数据

根据 id 删除

// 1. 获取数据库对象
const db = wx.cloud.database()
// 2. 获取操作的集合
const stuCollect = db.collection('students')

Page({
  onDelete() {
    // 3. 根据id删除某一条数据  =>  id去数据库里看即可
    stuCollect.doc('a64480e663f0753e000826875146d365')
      .remove()
      .then(res => {
        console.log(res);
      })
  }
})

根据 条件 删除

// 1. 获取数据库对象
const db = wx.cloud.database()
// 2. 获取操作的集合
const stuCollect = db.collection('students')

Page({
  // 3. 根据条件删除数据
  onDelete() {
    // 删除 名称 => coder 的数据
    stuCollect.where({
      name: 'coder'
    })
      .remove()
      .then(res => {
        console.log(res);
      })

    // 删除 年龄 => 大于16岁 的数据
    // 01.拿到查询指令
    const cmd = db.command
    stuCollect.where({
      // 02.使用查询指令  gt => >   lt => <
      age: cmd.gt(16)
    })
      .remove()
      .then(res => {
        console.log(res);
      })
  }
})

修改数据

修改单条数据

更新数据
update : 更新(增加)某一个字段
// 1. 获取数据库对象
const db = wx.cloud.database()
// 2. 获取操作的集合
const stuCollect = db.collection('students')

Page({
  // 修改
  onEdit() {
    stuCollect.doc('632b810463f08152000634f45aa33965')
      // update : 修改某一个字段
      .update({
        data: {
          age: 99
        }
      }).then(res => {
        console.log(res);
      })
  }
})
替换数据
set : 使用新对象替换原来对象
// 1. 获取数据库对象
const db = wx.cloud.database()
// 2. 获取操作的集合
const stuCollect = db.collection('students')

Page({
  // 修改
  onEdit() {
    stuCollect.doc('2cc84e2663ef492f00c7ecda28da87f4')
      // set : 原数据被全部替换
      .set({
        data: {
          age: 99
        }
      }).then(res => {
        console.log(res);
      })
  }
})

修改多条数据

// 1. 获取数据库对象
const db = wx.cloud.database()
// 2. 获取操作的集合
const stuCollect = db.collection('students')

Page({
  // 修改
  onEdit() {
    // 拿到查询指令
    const cmd = db.command
    stuCollect.where({
      // 条件 : 年龄小于30岁的人
      age: cmd.lt(30)
    }).update({
      data: {
        age: 20
      }
    }).then(res => {
      console.log(res);
    })
  }
})

查找数据

查询数据的方式 :

  • 方式一:通过ID查询精确的某一条数据

  • 使用doc查询ID

  • 方式二:根据条件查询满足条件的数据

  • 使用where作为条件

  • 方式三:通过指令过滤数据

  • 使用db.command的指令

  • eq => 等于

  • neq => 不等于

  • lt => 小于

  • lte => 小于或等于

  • gt => 大于

  • gte => 大于或等于

  • in => 字段值在给定数组中 ( name : cmd.in['coder','star'] )

  • nin => 字段值不在给定数组中

  • 方式四:通过正则表达式匹配符合的数据

  • 使用db.RegExp创建正则规则

  • 方式五:获取整个集合的数据(小程序端一次性最多20条,云函数中可以获取100条)

  • 直接调用get

  • 方式六:过滤、分页、排序查询数据

  • 使用field、skip、limit、orderBy

方式一 : 精准查询

// 1. 获取数据库对象
const db = wx.cloud.database()
// 2. 获取操作的集合
const yzCollect = db.collection('YZ')

Page({
  onQuery() {
    // 方式一 : 根据id查询某条数据
    yzCollect.doc('663f243e63f07f9700071256127340a0')
      .get()
      .then(({ data }) => {
        console.log(data);
      })
  }
})

方式二 : 条件查询

// 1. 获取数据库对象
const db = wx.cloud.database()
// 2. 获取操作的集合
const yzCollect = db.collection('YZ')

Page({
  onQuery() {
    // 方式二 : 根据条件查询 => 查询到的是多条数据
    yzCollect.where({
      // 不是模糊查询,但是可能是同名的
      nickname: "小野静奈",
    })
      .get()
      .then(({ data }) => {
        console.log(data); // [ {...} ]
      })
  }
})

方式三 : 指令查询

// 1. 获取数据库对象
const db = wx.cloud.database()
// 2. 获取操作的集合
const yzCollect = db.collection('YZ')

Page({
  onQuery() {
    // 方式三 : 查询指令 => gt => 大于  lt => 小于

    // 01 - 获取查询指令
    const _ = db.command
    yzCollect.where({
      // 02 - 使用查询指令
      rid: _.lt(9000000),
    })
      .get()
      .then(({ data }) => {
        console.log(data); // [ {...},{...} ] 小程序端一次性最多返回20条,可做分页查询
      })
  }
})

方式四 : 正则查询

// 1. 获取数据库对象
const db = wx.cloud.database()
// 2. 获取操作的集合
const yzCollect = db.collection('YZ')

Page({
  onQuery() {
    // 方式四 : 正则表达式查询  =>  查询包含 字母z 的数据  =>  模糊查询
    yzCollect.where({
      // nickname: db.RegExp({
      //   regexp:'z', // 包含z
      //   options:'i' // 忽略大小写
      // }),
      nickname: /z/ig
    })
      .get()
      .then(({ data }) => {
        console.log(data); // [ {...},{...} ] 小程序端一次性最多返回20条,可做分页查询
      })
  }
})

方式五 : 集合查询

// 1. 获取数据库对象
const db = wx.cloud.database()
// 2. 获取操作的集合
const yzCollect = db.collection('YZ')

Page({
  onQuery() {
    // 方式五 : 获取整个集合中的数据 => 直接get
    yzCollect
      .get()
      .then(({ data }) => {
        console.log(data); // [ {...},{...} ] 小程序端一次性最多返回20条,可做分页查询
      })
  }
})

方式六 : 综合查询

// 1. 获取数据库对象
const db = wx.cloud.database()
// 2. 获取操作的集合
const yzCollect = db.collection('YZ')

Page({
  // 方式六 : 综合查询
  /**
   * skip    =>   offset偏移量           =>  跳过几条数据
   * limit   =>   size                  =>  拿几条数据
   * orderBy =>   排序('des','方式')    =>  升序:asc  |  降序 : desc
   * field   =>   过滤字段               =>  拿想要的数据字段
   */
  // 
  onQuery() {
     
      // 过滤字段 => 拿 _id,nickname,rid 三个字段
      .field({
        _id: true,
        nickname: true,
        rid: true
      })
      // 跳过0条数据
      .skip(0)
      // 拿5条数据
      .limit(5)
      // 排序 => 根据rid排序,升序
      .orderBy('rid', 'asc')
      .get()
      .then(({ data }) => {
        console.log(data); // [ {_id:'', nickname:'', rid:''},{...} ] 
      })
  }
})

4. 案例

效果

wxml

<view class="nav">
  <block wx:for="{
    
    {dataList}}"
         wx:key="index">
    <view class="item">
      <view class="notice">
        <view size="mini"
              class="btn"
              bindtap="tabEdit"
              data-item="{
    
    {item}}"
              data-index="{
    
    {index}}">Edit</view>
        <text>{
    
    {item.nickname}}</text>
        <view size="mini"
              class="btn"
              bindtap="tabDel"
              data-item="{
    
    {item}}"
              data-index="{
    
    {index}}">Del</view>
      </view>
      <image src="{
    
    {item.roomSrc}}"
             mode="widthFix" />
    </view>
  </block>
</view>

wxss

.nav {
  padding: 20rpx;
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
}

.item {
  width: 48%;
  margin-bottom: 30rpx;
  border-radius: 40rpx;
}

.notice {
  font-size: 30rpx;
  line-height: 40rpx;
  display: flex;
  align-items: center;
  justify-content: space-between;
  color: pink;
}

.btn {
  font-size: 24rpx;
  color: gray;
}

image {
  width: 100%;
}

js

// 获取数据库对象
const db = wx.cloud.database()
// 获取集合
const yzCollect = db.collection('YZ')
Page({
  data: {
    dataList: [],
    page: 0,
    pageSize: 10
  },
  onLoad() {
    this.getDataList()
  },
  // 上拉加载更多
  onReachBottom() {
    this.getDataList()
  },

  /**
   * 方法
   */

  // 获取数据
  getDataList() {
    const { page, pageSize, dataList } = this.data
    yzCollect.field({
      nickname: true,
      roomName: true,
      roomSrc: true,
    })
      .skip(page * pageSize)
      .limit(pageSize)
      .get()
      .then(({ data }) => {
        console.log(data);
        // 保存数据
        this.setData({
          dataList: [...dataList, ...data]
        })
        this.data.page = page + 1
      })
  },
  // 编辑
  async tabEdit(e) {
    const { item, index } = e.currentTarget.dataset
    const newName = item.nickname + 'Q'
    // 更改数据库数据
    const { errMsg } = await yzCollect.doc(item._id).update({
      data: {
        nickname: newName
      }
    })
    if (errMsg !== 'document.update:ok') {
      return wx.showToast({
        title: '修改失败',
        icon: 'none'
      })
    }
    // 更改页面中数据
    this.setData({
      ['dataList[' + index + '].nickname']: newName
    })
    wx.showToast({
      title: '修改成功',
      icon: 'none'
    })
  },
  // 删除
  async tabDel(e) {
    const { item, index } = e.currentTarget.dataset
    // 删除数据库数据
    const { errMsg } = await yzCollect.doc(item._id).remove()
    if (errMsg !== 'document.remove:ok') {
      return wx.showToast({
        title: '删除失败',
        icon: 'none'
      })
    }
    // 删除页面中数据
    this.data.dataList.splice(index, 1)
    this.setData({
      dataList: this.data.dataList
    })
    wx.showToast({
      title: '删除成功',
      icon: 'none'
    })
    // 判断当前页面数量是否小于pageSize,在第一页时可能会出现镂空现象
    if (this.data.dataList.length < this.data.pageSize) {
      this.getDataList()
    }
  },
})

四、云存储

1. 概念

网址 : 微信开发文档 - 云存储

云存储用于将文件存储到云端 :

  • 云存储提供高可用、高稳定、强安全的云端存储服务

  • 持任意数量和形式的非结构化数据存储,如视频和图片

  • 并在控制台进行可视化管理

云存储常见的操作 :

  • 上传文件到云存储中(图片、视频、音频等等都可以)

  • 获取文件的临时链接(在外网可以访问)

  • 下载文件到本地(本地文件缓存)

  • 将云存储中的文件删除

2. 操作云存储 - 控制台操作

01 - 上传

图片、视频、音频等

02 - 页面展示

3. 操作云存储 - 代码操作

上传操作

Page({
  data: {
    imagePath: ""
  },
  
  // 上传文件
  async onUploadTap() {
    // 1. 选中本地文件( 相册、拍照 )
    const { type, errMsg, tempFiles } = await wx.chooseMedia({
      // 设定一次只能传一张图片
      count: 0
    })
    if (errMsg !== 'chooseMedia:ok') {
      return wx.showToast({
        title: '上传失败',
      })
    }
    console.log(type, errMsg, tempFiles);
    // 2. 获取照片
    const imagePath = tempFiles[0].tempFilePath
    // 3. 因为图片名称容易重复,所以这里设定一下
    const imageName = this.setImageName(imagePath)
    // 4. 将照片上传到云存储中
    const uploadRes = await wx.cloud.uploadFile({
      // 文件路径 => 文件名称,如果在images文件家中,前面带上即可 => images/abc.png
      cloudPath: 'images/' + imageName,
      // 指定要上传的文件的小程序临时文件路径
      filePath: imagePath,
    })
    console.log(uploadRes);
    if (uploadRes.errMsg !== 'cloud.uploadFile:ok') {
      return wx.showToast({
        title: '上传失败',
      })
    }
    wx.showToast({
      title: '上传成功',
    })
    // 5. 页面展示
    this.setData({
      imagePath: uploadRes.fileID
    })
  },

  // 图片名称设定
  setImageName(imagePath) {
    // 1. 时间戳
    const timeStamp = new Date().getTime()
    // 2. openid
    const openid = 'openid'
    // 3. 文件后缀名  pop => 拿到最后一个元素   
    const extension = imagePath.split(".").pop()
    // 返回拼接名称
    return `${timeStamp}_${openid}.${extension}`
  }
})

下载操作

Page({
  data: {
    imagePath: ""
  },

  // 一、点击下载
  onDownload() {
    // 1. 获取手机相册权限
    wx.authorize({
      scope: 'scope.writePhotosAlbum',
      success: () => {
        // 2. 从云存储中获取下载的文件路径
        this.getDownPath()
      },
      fail: () => {
        wx.showToast({
          title: '未授权,请前往微信设置页面中打开授权',
          icon: 'none'
        })
      }
    })
  },

  // 二、获取下载的文件地址
  async getDownPath() {
    //  根据fileID获取下载的文件路径
    const { errMsg, tempFilePath } = await wx.cloud.downloadFile({
      // fileID
      fileID: "cloud://xuanyu-dev"
    })
    if (errMsg !== 'downloadFile:ok') {
      return wx.showToast({
        title: '下载失败',
        icon: 'none'
      })
    }
    // 3. 保存文件到手机相册
    this.saveFile(tempFilePath)
    // 也可展示到页面上
    this.setData({
      imagePath: tempFilePath
    })
  },

  // 三、保存文件到手机相册
  saveFile(filePath) {
    // 下载图片到手机本地
    wx.saveImageToPhotosAlbum({
      filePath,
      success: ({ errMsg }) => {
        if (errMsg !== 'saveImageToPhotosAlbum:ok') {
          return wx.showToast({
            title: '下载失败',
            icon: 'none'
          })
        }
        wx.showToast({
          title: '下载成功',
          icon: 'none'
        })
      }
    })
  }
})

删除操作

Page({
  // 点击删除
  async onDelete() {
    const { errMsg } = await wx.cloud.deleteFile({
      fileList: [
        // fileID
        'cloud://xuanyu-dev'
      ],
    })
    if (errMsg !== 'cloud.deleteFile:ok') {
      return wx.showToast({
        title: '删除失败',
        icon: 'none'
      })
    }
    wx.showToast({
      title: '删除成功',
      icon: 'none'
    })
  },
})

临时链接

为什么要获取临时链接 :

  • 我们将文件上传到云存储后,可以通过fileID在小程序中直接访问

  • 但是,如果我们希望在小程序以外的地方访问(比如浏览器、手机端),那么fileID是不可以的

  • 这个时候,我们可以通过获取临时链接,该链接可以在小程序以外访问

  • 注意:文件链接有效期为两个小时

Page({
  // 生成临时文件链接
  async onTemplate() {
    // 1. 请求临时链接
    const { errMsg, fileList } = await wx.cloud.getTempFileURL({
      fileList: [
        // fileID
        'cloud://xuanyu-dev',
        'cloud://xuanyu-dev'
      ],
    })
    if (errMsg !== 'cloud.getTempFileURL:ok') {
      return wx.showToast({
        title: '生成链接失败',
        icon: 'none'
      })
    }
    // 2. 获取结果
    const resUrl = fileList.map(item => {
      return item.tempFileURL
    })
    console.log(resUrl);
    wx.showToast({
      title: '生成链接成功',
      icon: 'none'
    })
  },
})

五、云函数和云调用

1. 概念

云函数即在云端(服务器端)运行的函数 :

  • 在物理设计上,一个云函数可由多个文件组成,占用一定量的CPU 内存等计算资源

  • 云函数完全独立,可分别部署在不同的地区

  • 开发者无需购买、搭建服务器,只需编写函数代码并部署到云端即可在小程序端调用

  • 同时云函数之间也可互相调用

云函数的编写方式 :

  • 一个云函数的写法与一个在本地定义的 JavaScript 方法无异,代码运行在云端 Node.js 中

  • 当云函数被小程序端调用时,定义的代码会被放在Node.js 运行环境中执行

  • 可以如在 Node.js 环境中使用 JavaScript 一样在云函数中进行网络请求等操作,而且还可以通过云函数后端 SDK搭配使用多种服务,比如使用云函数 SDK 中提供的数据库和存储 API 进行数据库和存储的操作

云开发的云函数的独特优势在于与微信登录鉴权的无缝整合 :

  • 当小程序端调用云函数时,云函数的传入参数中会被注入小程序端用户的 openid,开发者无需校验 openid 的正确性因为微信已经完成了这部分鉴权,开发者可以直接使用该 openid

云函数作用 :

  • 在云函数中对云数据库进行操作

  • 对结果进行某种转换,再返回到小程序端

  • 在云函数中对云存储进行操作

  • 进行查询、上传、删除等操作

  • 向其他服务器发送请求

  • 请求到数据后,再返回到小程序端(云函数中对域名、ip没有限制)

  • . . . . . .

2. 使用过程

01 - 选择环境

02 - 同步云函数

03 - 下载代码到本地

04 - 创建云函数

05 - 编写代码逻辑

// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境


// 云函数入口函数
exports.main = async (event, context) => {
  return 'hello world'
}

06 - 将云函数上传到云端

07 - 小程序中对云函数调用

Page({
  async onLoad() {
    // 1. 调用云函数
    const { errMsg, requestID, result } = await wx.cloud.callFunction({
      // 2. 指定调用哪个云函数
      name: 'testFunc'
    })
    console.log(result); // 'hello world'
  }
})

3. 基本使用

案例 : 云函数来计算两个数字的和

01 - 本地代码

Page({
  async onLoad() {
    // 1. 调用云函数
    const { errMsg, requestID, result } = await wx.cloud.callFunction({
      // 2. 指定调用哪个云函数
      name: 'testFunc',
      // 3. 传入数据到云函数
      data: {
        num1: 10,
        num2: 20
      }
    })
    console.log(result); // 30
  }
})

02 - 云函数代码

// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境


// 云函数入口函数
exports.main = async (event, context) => {
  // 1. 获取调用者传入的参数,就是在data中传过来的参数
  // console.log(event); // 因为显示在云端,所以这样是看不到结果的
  const { num1, num2 } = event
  
  // 2. 返回结果
  return num1 + num2
}

03 - 部署云函数

右键,上传并部署即可

4. 云函数代码调试

云端测试

缺点 : 看不到打印信息

01 - 找到云函数

02 - 云端测试

本地调试

01 - 找到云函数

02 - 本地调试

安装依赖
开启成功
重新请求
更改代码

5. 高级使用

云函数 - 获取openID

微信内部做好了身份鉴权,在云函数中可直接拿到登录者的openID
openid可以用于作为用户身份的标识符,在云开发中可以获取用户openid来验证用户是否已经登录

在云函数中获取微信调用上下文 :

  • Cloud.getWXContext(): Object

云函数

// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境

// 云函数入口函数
/**
 * event   :  传递过来的参数
 * context :  node运行环境上下文,一般不会用到
 */
exports.main = async (event, context) => {
  // 1. 获取到微信的上下文
  const wxContext = cloud.getWXContext()

  return {
    event,
    openid: wxContext.OPENID,
    appid: wxContext.APPID,
    unionid: wxContext.UNIONID,
  }
}

本地调用

Page({
  async onLoad() {
    // 1. 调用云函数
    const { errMsg, requestID, result } = await wx.cloud.callFunction({
      // 2. 指定调用哪个云函数
      name: 'getOpenid',
    })
    console.log(errMsg, requestID, result); 
  }
})

云函数 – 操作云数据库

小程序端口对数据库的操作有限制 :

  • 小程序端一次最多获取20条数据 => 云函数最多100条

  • 小程序端一次性删除、修改多条数据可能会报警告 => 云函数中没有限制

云函数

// 云函数入口文件
const cloud = require('wx-server-sdk')

cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境

// 云函数入口函数
exports.main = async (event, context) => {
  // 1. 获取数据库
  const db = cloud.database()
  // 2. 获取集合
  const _ = db.collection('YZ')
  // 3. 从集合中查询数据
  return await _.get()
}

本地调用

Page({
  async onLoad() {
    // 1. 调用云函数
    const { result } = await wx.cloud.callFunction({
      // 2. 指定调用哪个云函数
      name: 'getYZdata',
    })
    console.log(result.data); // [{...}, {...}, {...}, ...]
  }
})

云函数 – 操作云存储

云函数

// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境

// 云函数入口函数
exports.main = async (event, context) => {
  // 1. 下载操作 => 下载下来文件,不是地址,不知道干嘛用的,又不能保存在本地
  const { errMsg: downErrMsg, fileContent } = await cloud.downloadFile({
    // fileID
    fileID: "cloud://xuanyu-dev"
  })
  if (downErrMsg !== 'downloadFile:ok') {
    return downErrMsg
  }
  // return fileContent.toString('utf8')

  // 2. 删除操作
  const { errMsg: delErrMsg } = await cloud.deleteFile({
    fileList: [
      'cloud://xuanyu-dev'
    ],
  })
  if (delErrMsg !== 'deleteFile:ok') {
    return delErrMsg
  }
  return 'OK'
}

本地调用

Page({
  data: {
    qrCodeUrl: ''
  },
  async onLoad() {
    // 1. 调用云函数
    const { result } = await wx.cloud.callFunction({
      // 2. 指定调用哪个云函数
      name: 'fetchData',
    })
    console.log(result);
  }
})

云函数 – 发送http请求

对于小程序某些域名的限制无法配置时,我们可以通过云函数作为代理来请求数据,再返回给小程序端
需要使用axios,所以需安装
ps :
npm i [email protected] => 如果安装高版本的,可能会出问题

返回的结果时,如果出现以下问题,可能是格式问题,返回.data或者详细的数据即可

云函数

// 云函数入口文件
const cloud = require('wx-server-sdk')
const axios = require('axios')
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境

// 云函数入口函数
exports.main = async (event, context) => {
  // 1. 从其他服务器中请求数据
  const res = await axios.get('http://www.baidu.com')
  // 2. 对数据进行转换

  // 3. 返回数据到小程序端   =>   这里要返回.data   否则可能会报错
  return res.data
}

本地调用

Page({
  async onLoad() {
    // 1. 调用云函数
    const { result } = await wx.cloud.callFunction({
      // 2. 指定调用哪个云函数
      name: 'fetchData',
    })
    console.log(result);
  }
})

云函数 – 生成小程序码

网址 : 微信官方文档 - 生成二维码

云函数

// 云函数入口文件
const cloud = require('wx-server-sdk')
cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) // 使用当前云环境

// 云函数入口函数
exports.main = async (event, context) => {
  // 1. 生成小程序码
  const { contentType, errMsg: codeErrMsg, buffer } = await cloud.openapi.wxacode.createQRCode({
    "path": 'pages/cloud-database/index',
    "width": 320
  })
  if (codeErrMsg !== 'openapi.wxacode.createQRCode:ok') {
    // 生成二维码失败
    return codeErrMsg
  }

  // 2. 获取图片数据,上传到云存储中
  const timeStamp = new Date().getTime()
  const openid = cloud.getWXContext().OPENID
  const ext = contentType.split('/').pop()
  const { errMsg: uploadErrMsg, fileID } = await cloud.uploadFile({
    // 文件内容,注 : 这里没有filePath
    fileContent: buffer,
    cloudPath: `qrcode_${timeStamp}_${openid}.${ext}`
  });
  if (uploadErrMsg !== 'uploadFile:ok') {
    // 存储二维码失败
    return uploadErrMsg
  }

  // return fileID
  // 可直接返回fileID | 或者多一步,返回临时路径
  // 3. 获取图片临时路径
  const { errMsg: getTempErrMsg, fileList } = await cloud.getTempFileURL({
    fileList: [fileID]
  })
  if (getTempErrMsg !== 'getTempFileURL:ok') {
    // 获取二维码失败
    return getTempErrMsg
  }

  // 4. 返回临时图片路径
  return fileList[0].tempFileURL
}

本地调用

Page({
  data: {
    qrCodeUrl: ''
  },
  async onLoad() {
    // 1. 调用云函数
    const { result } = await wx.cloud.callFunction({
      // 2. 指定调用哪个云函数
      name: 'fetchData',
    })
    this.setData({
      qrCodeUrl: result
    })
    console.log(result);
  }
})

猜你喜欢

转载自blog.csdn.net/a15297701931/article/details/129055067