微信小程序 之 云开发

news2024/11/29 2:49:35

一、概念

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

  • 网址 : wxcloud

云函数

// 云函数入口文件
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 axios@0.27.2 => 如果安装高版本的,可能会出问题

返回的结果时,如果出现以下问题,可能是格式问题,返回.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);
  }
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/364021.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python自动化测试之登录脚本

登录脚本环境准备1、安装selenium模块2、安装浏览器驱动器代码1、登录代码2、xpath定位元素标签环境准备 前提已经安装好python、pycharm&#xff0c;配置了对应的环境变量。 1、安装selenium模块 文件–>设置—>项目&#xff1a;script---->python解释器---->s…

Spring自动装配的底层逻辑

Spring是如何自动装配Bean的&#xff1f;看源码一些自己的理解&#xff0c;如有错漏&#xff0c;请指正 使用Spring之前我们要先去web.xml中设置一下Spring的配置文件&#xff0c;在Spring的配置文件中&#xff0c;是通过component-scan扫描器去扫描base-package底下所有的类装…

【基础算法】哈希表(拉链法)

&#x1f339;作者:云小逸 &#x1f4dd;个人主页:云小逸的主页 &#x1f4dd;Github:云小逸的Github &#x1f91f;motto:要敢于一个人默默的面对自己&#xff0c;强大自己才是核心。不要等到什么都没有了&#xff0c;才下定决心去做。种一颗树&#xff0c;最好的时间是十年前…

【C++的OpenCV】第四课-OpenCV图像常用操作(一):Mat对象深化学习、灰度、ROI

我们开始图像处理的基本操作的了解一、图像对象本身的加深学习1.1 Mat对象和ROI1.1.1 创建一个明确的Mat对象1.1.2 感兴趣的区域ROI二、图像的灰度处理2.1 概念2.2 cvtColor()函数2.3 示例一、图像对象本身的加深学习 1.1 Mat对象和ROI 这是一个技术经验的浅尝&#xff0c;所以…

什么是 CSAT?这份客户满意度流程指南请查收

什么是 CSAT&#xff1f;如何计算我的客户满意度分数&#xff1f;大中型公司应该熟悉这些术语。以下文章旨在教您有关客户满意度流程的所有内容 - 基本的CSAT概念、创建CSAT调查的好处、如何创建CSAT调查。配图来源&#xff1a; SaleSmartly(ss客服) 一、什么是 CSAT&#xff1…

算法笔记(十二)—— Manacher算法(回文子串)

计算字符串内的最大回文子串&#xff0c;常用的暴力扩散在应对长度为偶数的回文时会遇到一些问题。 Manacher基础&#xff1a;对字符串进行填充&#xff0c;在字符串开头结尾以及字符间填充‘#’&#xff0c;以来应对偶数回文时的问题。&#xff08;这是采用暴力扩再除2&#x…

[黑马程序员SSM框架教程]03 spring核心概念

IOC/DI 书写现状&#xff1a;耦合度偏高 如图&#xff1a;传统书写代码左边业务层需要new一个对象进行业务实现。当数据层优化代码BookDaoImpl2就需要动业务层代码重新修改new的对象。导致代码耦合度偏高。 解决办法&#xff1a;使用对象&#xff0c;不要主动new对象&#xff…

kubernetes traefik ingress 安装部署以及使用和注意点

1、简介 Traefik 是一款 open-source 边缘路由器&#xff0c;可让您轻松地发布服务. 它接收来自您的系统请求&#xff0c;并找出负责处理它们的后端服务组件。 traefik 与众不同在于它能够自动发现适合您服务的配置。 当 Traefik 检查您的基础设施时&#xff0c;它会发现相关信…

Redisson实现分布式锁

目录Redisson简介Redisson实现分布式锁步骤引入依赖application.ymlRedisson 配置类Redisson分布式锁实现Redisson简介 Redis 是最流行的 NoSQL 数据库解决方案之一&#xff0c;而 Java 是世界上最流行&#xff08;注意&#xff0c;没有说“最好”&#xff09;的编程语言之一。…

Matthew Ball:十多年后AR/VR为何依然发展缓慢?

2010年&#xff0c;Magic Leap和微软就开始研发AR技术&#xff0c;直到2012年Oculus才成立&#xff0c;AR/VR经过了13年左右的时间&#xff0c;虽然受到越来越多人关注&#xff0c;但发展依然缓慢。VR的主要应用场景还是游戏&#xff0c;但VR游戏只是游戏市场的一个分支&#x…

第七章.深度学习

第七章.深度学习 7.1 深度学习 深度学习是加深了层的深度神经网络。 1.加深层的好处 1).可以减少网络的参数数量 5*5的卷积运算示例&#xff1a; 重复两次3*3的卷积层示例&#xff1a; 图像说明&#xff1a; ①.一次5 * 5的卷积运算的区域可以由两次3 * 3的卷积运算抵消&a…

服务端开发Java之备战秋招面试篇1

在这个面试造火箭工作拧螺丝的时代背景下&#xff0c;感觉不是很好&#xff0c;不过还好也是拿到了还行的offer&#xff0c;准备去实习了&#xff0c;接下来就是边实习边准备秋招了&#xff0c;这半年把&#xff08;技术栈八股文面经算法题项目&#xff09;吃透&#xff0c;希望…

打破数据孤岛,Apache Doris 助力纵腾集团快速构建流批一体数仓架构|最佳实践

福建纵腾网络有限公司&#xff08;简称“纵腾集团”&#xff09;成立于 2009 年&#xff0c; 以“全球跨境电商基础设施服务商”为企业定位&#xff0c;聚焦跨境仓储与物流&#xff0c; 为全球跨境电商商户、出口贸易企业、出海品牌商提供海外仓储、商业专线物流、定制化物流等…

【C++】vector 模拟实现

vectorvector 容器vector 基本使用vector 定义库中各类接口的使用迭代器容量相关接口元素访问相关接口元素修改相关接口模拟实现 vector前期准备构造与析构赋值运算符重载迭代器相关容量相关元素访问相关元素的修改相关二维数组的创建对于自定义类型数据的测试vector 容器 C S…

Python实战之小说下载神器(二)整本小说下载:看小说不用这个程序,我实在替你感到可惜*(小说爱好者必备)

前言 这次的是一个系列内容给大家讲解一下何一步一步实现一个完整的实战项目案例系列之小说下载神器&#xff08;二&#xff09;&#xff08;GUI界面化程序&#xff09; 单章小说下载保存数据——整本小说下载 你有看小说“中毒”的经历嘛&#xff1f;小编多多少少还是爱看小说…

基于react+nodejs+mysql开发用户中心,用于项管理加入的项目的用户认证

基于reactnodejsmysql开发用户中心&#xff0c;用于项管理加入的项目的用户认证用户中心功能介绍页面截图后端采用架构user表projects表project_user表仓库地址用户中心功能介绍 用户中心项目&#xff0c;用于统一管理用户信息、登录、注册、鉴权等 功能如下&#xff1a; 用…

[qiankun]实战问题汇总

[qiankun]实战问题汇总ERROR SyntaxError: Cannot use import statement outside a module问题分析解决方案子应用命名问题问题分析解决方案jsonpFunction详细错误信息问题分析解决方案微应用的注册问题Uncaught Error: application cli5-beta6-test-name died in status LOADI…

2月,真的不要跳槽。

新年已经过去&#xff0c;马上就到金三银四跳槽季了&#xff0c;一些不满现状&#xff0c;被外界的“高薪”“好福利”吸引的人&#xff0c;一般就在这时候毅然决然地跳槽了。 在此展示一套学习笔记 / 面试手册&#xff0c;年后跳槽的朋友可以好好刷一刷&#xff0c;还是挺有必…

Zebec官方辟谣“我们与Protradex没有任何关系”

近日&#xff0c;流支付协议Zebec Protocol在其官方推特上&#xff0c;发表了一个辟谣澄清声明。该条推特推文表示&#xff0c;“Zebec 与 Protradex 没有任何关系或产生关联。他们&#xff08; Protradex &#xff09;声称Zebec 生态正在支持他们&#xff0c;但这是错误的。随…

上海亚商投顾:沪指失守3300点 卫星导航概念全天强势

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。市场情绪指数早间低开后震荡回升&#xff0c;沪指盘中一度翻红&#xff0c;随后又再度走低&#xff0c;创业板指午后跌近1%。…