14.0 配置腾讯云Cos
目标
: 配置一个腾讯云cos
由于上课的开发的特殊性,我们不希望把所有的图片都上传到我们自己的官方服务器上,这里我们可以采用一个腾讯云的图片方案
- 用户上传 =》 腾讯云服务器 =》 返回地址 =》 地址存入数据库
- 选择 对象存储 cos 模块
- 创建存储桶(选择 公有读私有写)
- 设置 cors 规则 (来源选择 * , 操作全部勾选)
因为我们本身没有域名,所以这里设置成***
**,仅限于测试,正式环境的话,这里需要配置真实的域名地址
15.0 封装上传图片组件-上传组件需求分析
目标
梳理整个的上传过程
- 初始化cos对象参数
名称 | 描述 |
---|---|
SecretId | 开发者拥有的项目身份识别 ID,用以身份认证,可在 API 密钥管理 页面获取 |
SecretKey | 开发者拥有的项目身份密钥,可在 API 密钥管理 页面获取 |
注意,上述的参数我们在本次开发过程中,直接将参数放置在前端代码中存储,但是腾讯云本身是不建议这么做的,因为**
敏感信息
**放在前端很容易被捕获,由于我们本次是测试研发,所以这个过程可以忽略正确的做法应该是,通过网站调用接口换取敏感信息
- 实例化 上传sdk
var cos = new COS({
SecretId: 'COS_SECRETID', // 身份识别 ID
SecretKey: 'COS_SECRETKEY', // 身份密钥
});
到目前为止,我们上传图片准备的内容就已经OK,接下来,我们在**
src/componets
** 新建一个**ImageUpload
** 组件
该组件需要满足什么要求呢?
- 可以显示传入的图片地址
- 可以删除传入的图片地址
- 可以上传图片到云服务器
- 上传到腾讯云之后,可以返回图片地址,显示
- 上传成功之后,可以回调成功函数
16.0 封装上传组件-代码实现
**目标
**实现上传组件的代码部分
JavaScript SDK 需浏览器支持基本的 HTML5 特性(支持 IE10 以上浏览器),以便支持 ajax 上传文件和计算文件 MD5 值。
16.1 新建文件上传组件
- 安装JavaScript SDK
npm i cos-js-sdk-v5 --save
- 新建上传图片组件**
src/components/ImageUpload/index.vue
上传组件,我们可以沿用element的el-upload组件,并且采用照片墙的模式
list-type="picture-card"
- 放置el-upload组件
<template>
<el-upload list-type="picture-card">
<i class="el-icon-plus" />
</el-upload>
</template>
- 全局注册组件
import PageTools from './PageTools'
import UploadExcel from './UploadExcel'
import ImageUpload from './ImageUpload'
export default {
install(Vue) {
Vue.component('PageTools', PageTools) // 注册工具栏组件
Vue.component('UploadExcel', UploadExcel) // 注册导入excel组件
Vue.component('ImageUpload', ImageUpload) // 注册导入上传组件
}
}
16.2 点击图片进行预览
- 限定上传的图片数量和action
<template>
<el-upload action="#" list-type="picture-card" :limit="1" :on-preview="preview" :file-list="fileList" >
<i class="el-icon-plus" />
</el-upload>
</template>
action为什么给#, 因为前面我们讲过了,我们要上传到腾讯云,需要自定义的上传方式,action给个#防止报错
- 预览
data() {
return {
fileList: [{
url: 'https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=1970585368,2576171845&fm=26&gp=0.jpg'}], // 图片地址设置为数组
showDialog: false, // 控制显示弹层
imgUrl: ''
}
},
preview(file) {
// 这里应该弹出一个层 层里是点击的图片地址
this.imgUrl = file.url
this.showDialog = true
},
- 预览弹层
<el-dialog title="图片" :visible.sync="showDialog">
<img :src="imgUrl" style="width:100%" alt="">
</el-dialog>
16.3 根据上传数量控制上传按钮
- 控制上传显示
computed: {
// 设定一个计算属性 判断是否已经上传完了一张
fileComputed() {
return this.fileList.length === 1
}
},
<el-upload
:on-preview="preview"
:on-remove="handleRemove"
:on-change="changeFile"
:file-list="fileList"
list-type="picture-card"
action="#"
:limit="1"
:class="{disabled: fileComputed }"
>
<style>
.disabled .el-upload--picture-card {
display: none
}
</style>
16.4 删除图片和添加图片
- 删除文件
handleRemove(file) {
// file是点击删除的文件
// 将原来的文件给排除掉了 剩下的就是最新的数组了
this.fileList = this.fileList.filter(item => item.uid !== file.uid)
},
- 添加文件
// 修改文件时触发
// 此时可以用fileList 因为该方法会进来很多遍 不能每次都去push
// fileList因为fileList参数是当前传进来的最新参数 我们只需要将其转化成数组即可 需要转化成一个新的数组
// [] => [...fileList] [] => fileList.map()
// 上传成功之后 还会进来 需要实现上传代码的逻辑 这里才会成功
changeFile(file, fileList) {
this.fileList = fileList.map(item => item)
}
16.5 上传之前检查
控制上传图片的类型和上传大小, 如果不满足条件 返回false上传就会停止
:before-upload="beforeUpload" // 添加 事件
beforeUpload(file) {
// 要开始做文件上传的检查了
// 文件类型 文件大小
const types = ['image/jpeg', 'image/gif', 'image/bmp', 'image/png']
// 数组的 includes 方法 返回一个布尔值,表示某个数组是否包含给定的值,与字符串的includes方法类似。该方法属于 ES7 ,但 Babel 转码器已经支持。
if (!types.includes(file.type)) {
this.$message.error('上传图片只能是 JPG、GIF、BMP、PNG 格式!')
return false
}
// 检查大小
const maxSize = 5 * 1024 * 1024
if (maxSize < file.size) {
this.$message.error('图片大小最大不能超过5M')
return false
}
return true
}
16.6 上传动作调用上传腾讯云
- 上传动作为el-upload的http-request属性
:http-request="upload"
// 自定义上传动作 有个参数 有个file对象,是我们需要上传到腾讯云服务器的内容
upload(params) {
console.log(params.file)
}
我们需要在该方法中,调用腾讯云的上传方法
身份ID和密钥可以通过腾讯云平台获取
登录 访问管理控制台 ,获取您的项目 SecretId 和 SecretKey。
- 实现代码
import COS from 'cos-js-sdk-v5'
var cos = new COS({
SecretId: 'COS_SECRETID', // 身份识别 ID
SecretKey: 'COS_SECRETKEY', // 身份密钥
});
// 这个的,密钥在上面查找怎么获取
// 进行上传操作
upload(params) {
// console.log(params.file)
if (params.file) {
// 执行上传操作
cos.putObject({
Bucket: 'shuiruohanyu-106-1302806742', // 存储桶
Region: 'ap-beijing', // 地域
Key: params.file.name, // 文件名
Body: params.file, // 要上传的文件对象
StorageClass: 'STANDARD' // 上传的模式类型 直接默认 标准模式即可
// 上传到腾讯云 =》 哪个存储桶 哪个地域的存储桶 文件 格式 名称 回调
}, function(err, data) {
// data返回数据之后 应该如何处理
console.log(err || data)
})
}
}
16.7 上传成功之后处理返回数据
如何处理返回成功的返回数据
- 确定要上传记录id
currentFileUid: null, // 上传 id 添加一个data里面的数据
beforeUpload(file) {
// 先检查文件类型
const types = ['image/jpeg', 'image/gif', 'image/bmp', 'image/png']
if (!types.some(item => item === file.type)) {
// 如果不存在
this.$message.error('上传图片只能是 JPG、GIF、BMP、PNG 格式!')
return false // 上传终止
}
// 检查文件大小 5M 1M = 1024KB 1KB = 1024B
const maxSize = 5 * 1024 * 1024
if (file.size > maxSize) {
// 超过了限制的文件大小
this.$message.error('上传的图片大小不能大于5M')
return false
}
// 已经确定当前上传的就是当前的这个file了
this.currentFileUid = file.uid
return true // 最后一定要return true
},
- 处理返回数据
// 进行上传操作
upload(params) {
// console.log(params.file)
if (params.file) {
// 执行上传操作
cos.putObject({
Bucket: 'shuiruohanyu-106-1302806742', // 存储桶
Region: 'ap-beijing', // 地域
Key: params.file.name, // 文件名
Body: params.file, // 要上传的文件对象
StorageClass: 'STANDARD' // 上传的模式类型 直接默认 标准模式即可
// 上传到腾讯云 =》 哪个存储桶 哪个地域的存储桶 文件 格式 名称 回调
}, (err, data) => {
// data返回数据之后 应该如何处理
console.log(err || data)
// data中有一个statusCode === 200 的时候说明上传成功
if (!err && data.statusCode === 200) {
// 此时说明文件上传成功 要获取成功的返回地址
// fileList才能显示到上传组件上 此时我们要将fileList中的数据的url地址变成 现在上传成功的地址
// 目前虽然是一张图片 但是请注意 我们的fileList是一个数组
// 需要知道当前上传成功的是哪一张图片
this.fileList = this.fileList.map(item => {
// 去找谁的uid等于刚刚记录下来的id
if (item.uid === this.currentFileUid) {
// 将成功的地址赋值给原来的url属性
return {
url: 'http://' + data.Location, upload: true }
// upload 为true 表示这张图片已经上传完毕 这个属性要为我们后期应用的时候做标记
// 保存 => 图片有大有小 => 上传速度有快又慢 =>要根据有没有upload这个标记来决定是否去保存
}
return item
})
// 将上传成功的地址 回写到了fileList中 fileList变化 =》 upload组件 就会根据fileList的变化而去渲染视图
}
})
}
}
我们在fileList中设置了属性为upload为true的属性,表示该图片已经上传成功了,如果fileList还有upload不为true的数据,那就表示该图片还没有上传完毕
16.8 上传的进度条显示
为了再上传图片过程中显示进度条,我们可以使用element-ui的进度条显示当前的上传进度
- 放置进度条
<el-progress v-if="showPercent" style="width: 180px" :percentage="percent" />
percent: 0, // 进度条的百分比
showPercent: false,// 默认不显示进度条
- 通过腾讯云sdk监听上传进度
this.showPercent = true // 看完整代码 ,在上传文件的预验证里面
cos.putObject({
// 配置
Bucket: 'laogao-1302806742', // 存储桶名称
Region: 'ap-guangzhou', // 存储桶地域
Key: params.file.name, // 文件名作为key
StorageClass: 'STANDARD', // 此类写死
Body: params.file, // 将本地的文件赋值给腾讯云配置
// 进度条