第一个微信小程序 —— PuppyHome
最近一直忙着搞学校的icode比赛所以博客的更新就搁置了qwq,这个icode比赛我们是做一个小程序,而我是负责小程序的前端部分,这篇文章也是来记录一下第一次小程序的经历,技术性的东西估计不会讲太多,可能主要讲本项目如何使用腾讯云的COS对象存储以及一些开发中遇到的坑……
小程序介绍
这个小程序是一个用来服务于修勾的平台,主要用户功能有发布、收藏、删除领养公告以及领养自己喜欢的修勾,以及本项目的一大亮点——“拍照识修勾”即用户拍照后平台进行分析得出相似度最高的修勾品种,当然这一困难part主要是后端方面的工作(想看后端介绍的友友可以去友链里面勋哥的博客看),而我就负责前端的部分,具体小程序以及前端代码的github地址会在项目结束后会放在文章的最后……
开发实记
var that = this的声明
如若需要修改data里面的值并渲染到页面一般需要使用this.setData(),但是我们项目起初在调用wx.request()这个API时,在wx.request()里面使用this.setData()会报错,经过查询才知道要在wx.request()前面加上一下声明
1 | var that = this; |
而原因和this的作用域有关:
- 在Page({})里面,this关键字指代Page({})整个对象,因此可以通过this关键字访问或者重新设置Page({})里data的变量,但是在wx.request()这个API后this的指向就发生改变就无法使用this来获取Page({})对象
- 而解决方法就是在wx.request()外面先把this存在某个变量中即上述声明,此时that指代Page({})整个对象,也就能在wx.request()中使用that来访问Page({})对象
腾讯云COS对象存储介绍
在小程序中难免会碰到上传图片之类的操作,我们这个项目主要是在用户头像、公告发布、拍照识别等会用到图片上传,因为我们在数据库中图片是打算用一个字符串来存储(即图片链接),所以最后选择了腾讯云的COS对象存储,再将得到的图片链接传给后端,接下来就讲讲前期的准备工作
进入腾讯云官网(https://cloud.tencent.com ),产品栏找到存储中的对象存储,进入之后点击“立即使用”登录,这里我用的是小程序公众号的方式登录,然后就进入对象存储的控制台界面
创建存储桶
进入具体的某个存储桶后可以进行文件的上传,也可以创建文件夹对上传的文件进行分类存放,上传后就可以可以得到对应图片的url链接
腾讯云对象存储除了提供多种 API 接口,还提供了丰富多样的 SDK 供开发者使用,这个项目用的就是其中的小程序SDK(https://cloud.tencent.com/document/product/436/31953 )
腾讯云COS对象存储的小程序SDK使用
首先是安装小程序SDK,我用的是官网中手动安装的方式(具体可查看官网),并将cos-wx-sdk-v5.js放在utils的目录下
小程序里请求 COS 需要登录到 微信公众平台,选择开发 > 开发设置 > 服务器域名,配置域名白名单。SDK 使用到了两个接口:
cos.postObject 使用 wx.uploadFile 方法。
其他方法使用 wx. request 方法。
需要在对应白名单里,配置 COS 域名,白名单域名格式有两种:
如果是标准请求,可以配置存储桶域名作为白名单域名,例如:
https://examplebucket-1250000000.cos.ap-guangzhou.myqcloud.com
(本项目使用这个)如果小程序使用的存储桶多,可以选择后缀式请求 COS,只需要在 SDK 实例化时传入
ForcePathStyle: true
,这种方式需要配置地域域名作为白名单,例如:cos.ap-guangzhou.myqcloud.com
。
初始化及其配置:官网介绍了四种方式,本项目使用的是比较简便的格式4,在需要使用上传图片的页面js中进行cos的初始化及其配置
1
2
3
4
5
6
7
8
9var COS = require('../../../utils/cos-wx-sdk-v5.js'); //注意路径按照自己的更改
// 创建一个 COS SDK 实例
// SECRETID 和 SECRETKEY 请登录 https://console.cloud.tencent.com/cam/capi 进行查看和管理
var cos = new COS({
SecretId: 'SECRETID',
SecretKey: 'SECRETKEY',
SimpleUploadMethod: 'putObject', // 强烈建议,高级上传、批量上传内部对小文件做简单上传时使用putObject,sdk版本至少需要v1.3.0
});上传函数实现
第一种:直接点击按钮上传
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37UpLoadImg(){
var that = this;
// 选择图片上传
wx.chooseMedia({ //此API可以查看微信官方文档的具体参数信息
count: 1, // 上传1张图片
mediaType: ['image'],
sourceType: ['album','camera'], // 拍摄图片或从相册选择图片
success(res){
// 拿到本地的临时文件路径filePath,多张图片可以用for循环遍历上传
var filePath = res.tempFiles[0].tempFilePath;
// 截取filePath最后一个斜杆的后面部分作为cloudPath
var cloudPath = filePath.substr(filePath.lastIndexOf('/') + 1)
// 使用腾讯云COS对象存储
cos.postObject({
Bucket: 'Bucketname', //对象储存桶的名称
Region: 'ap-guangzhou', //所属地域
Key: 'dir/' + cloudPath, //存储在dir文件夹里面,如果没有区分文件夹就直接填cloudPath
FilePath: filePath, // 本地的临时文件路径
onProgress: function (info) {
console.log('进度条', JSON.stringify(info));
}
}, function (err, data) {
// 这里用的是回调函数的形式,也可以用promise方式
if (err) {
console.log('上传失败', err);
} else {
// 上传成功赋值toIdentifyUrl
that.setData({
// 最终的图片地址toIdentifyUrl在data里面有声明
// app.globalData.cdnHost是图片链接的公共前缀我放在app.js里面了
toIdentifyUrl: app.globalData.cdnHost + 'dir/' + cloudPath
})
}
});
}
})
}第二种:结合WeUI的mp-uploader组件进行上传(mp-uploader自带图片上传的相关参数)
WeUI的引入这里就不赘述了,首先是wxml的mp-uploader部分
1
2<!-- photo是最终存放上传成功图片的列表,一般一开始是空的 -->
<mp-uploader files="{{photo}}" max-count="1" max-size="{{10 * 1024 * 1024}}" title="照片:" tips="最多上传一张图片" size-type="{{sizeType}}" sourceType="{{sourceType}}" delete="{{true}}" select="{{selectFile}}" upload="{{uplaodFile}}" binddelete="delimg" bindfail="uploadError" bindsuccess="uploadSuccess"></mp-uploader>然后就是涉及到的上传图片的js代码,主要mp-uploader中5个函数的实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93var COS = require('../../../utils/cos-wx-sdk-v5.js'); // 图片上传所需接口
const app = getApp();
// 创建一个 COS SDK 实例
// SECRETID 和 SECRETKEY 请登录 https://console.cloud.tencent.com/cam/capi 进行查看和管理
var cos = new COS({
SecretId: 'SECRETID',
SecretKey: 'SECRETKEY',
SimpleUploadMethod: 'putObject', // 强烈建议,高级上传、批量上传内部对小文件做简单上传时使用putObject,sdk版本至少需要v1.3.0
});
Page({
data: {
photo: [],
//mp-uploader
sizeType: ['original'], //压缩上传,可以是['original', 'compressed']
sourceType: ['album', 'camera'], //相册,或拍照
maximgs: 1,
},
onLoad() {
this.setData({
//通过bind(this)将函数绑定到this上,以后函数内的this就是指全局页面
//setdata以后,这两个函数就可以传递给mp-uploader了
selectFile: this.selectFile.bind(this),
uplaodFile: this.uplaodFile.bind(this)
})
},
// 图片上传相关函数
// Func01:uplaodFile,必须返回Promise
uplaodFile(files) {
//Promise的callback里面必须resolve({urls})表示成功,否则表示失败
return new Promise((resolve, reject) => {
const tempFilePaths = files.tempFilePaths;
const that = this;
let finished = {
urls: []
} //本次上次成功的URLs存入这个变量,被success方法的e.detail承接
for (var i = 0; i < tempFilePaths.length; i++) {
let filePath = tempFilePaths[i] //原名
let cloudPath = new Date().getTime() + '-' + filePath.substr(filePath.lastIndexOf('/') + 1) //云存储文件名
cos.postObject({
Bucket: 'BucketName', //对象储存桶的名称
Region: 'ap-guangzhou', //所属地域
Key: 'dir/' + cloudPath, //存储在dir文件夹里面
FilePath: filePath,
onProgress: function (info) {
console.log('进度条', JSON.stringify(info));
}
}, function (err, data) {
// 这里用的是回调函数的形式,也可以用promise方式
if (err) {
console.log('上传失败', err);
} else {
finished.urls.push({
url: app.globalData.cdnHost + 'dogs/' + cloudPath
}) //成功一个存一个到本次上传成功列表
//如果本次上传的文件都完成 或全局已经存满1张,resolve退出
if (finished.urls.length === tempFilePaths.length || that.data.files.length + finished.urls.length == this.data.maximgs) {
resolve(finished)
}
}
});
}
})
},
// Func02:uploadSuccess,上传成功函数
uploadSuccess(e) {
console.log('upload success', e.detail)
// 将新上传的urls接到目前的photo上
this.data.photo = this.data.photo.concat(e.detail.urls)
this.setData({
photo: this.data.photo
})
wx.hideLoading()
},
// Func03:delimg删除图片
// detail为{index, item},index表示删除的图片的下标,item为图片对象。
delimg(e) {
this.data.photo.splice(this.data.photo.findIndex(item => item == e.detail.item), 1)
},
// Func04:uploadError,上传失败函数
uploadError(e) {
console.log('upload error', e.detail)
wx.hideLoading()
},
// Func05:selectFile,mpuploader选择图片时的过滤函数,返回true表示图片有效
selectFile(files) {
wx.showLoading({
title: '',
})
}
})
项目源码github地址
2023-3-21 13:55 项目基本完成,过段时间开源项目前端代码……
2023-4-23 8:31
- 前端项目代码github链接:
- B站演示视频链接: