目录
前言
vue项目中,使用element-ui的上传组件上传图片到OSS并预览。
一、主要用的有哪些依赖包?
1.element-ui
安装
npm i element-ui -S
2.ali-oss
安装
npm install ali-oss
3.v-viewer
安装
npm install v-viewer
二、使用步骤
1.引入库
在main.js中引入需要的组件库及css文件,如下:
// 全局引入element-ui
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
// 引入v-viewer
import Viewer from 'v-viewer'
import 'viewerjs/dist/viewer.css'
// 全局配置viewer 其他配置项可以参考文档
Vue.use(Viewer, {
defaultOptions: {
zIndex: 9999
}
})
2.封装上传图片和删除OSS图片的方法
2.1在使用OSS之前,需要先去OSS控制台做一些相应的操作。1.新建一个Bucket,上传的时候会使用到。2.需要配置跨域请求和相应的请求方式,便于开发调试。
tips:如果已经配置了跨域但是上传还是出现跨域问题,可以等会再上传,应该配置还没有生效。
2.2 开始封装方法
因为我们采用的是前端直接上传到OSS,所以要先通过后端获取到【region】【accessKeyId】【accessKeySecret】【Bucket】。封装方法就可以自由发挥了,可以参考OSS官方文档brower.js。代码如下:
// 引入依赖包
const OSS = require('ali-oss');
/*
上传方法
params:config,file
config:oss 相关配置参数
file: 上传的文件对象
*/
export function uploadImg(config, file) {
const client = new OSS({
// yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
region: config.region,
// 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
accessKeyId: config.osskeyId,
accessKeySecret: config.osskeySecret,
// 填写Bucket名称。
bucket: config.ossBucket
});
// 从输入框获取file对象,例如<input type="file" id="file" />。
// const data = document.getElementById('file').files[0];
// 创建并填写Blob数据。
//const data = new Blob('Hello OSS');
// 创建并填写OSS Buffer内容。
//const data = new OSS.Buffer('Hello OSS');
// 填写Object完整路径。Object完整路径中不能包含Bucket名称。
// 您可以通过自定义文件名(例如exampleobject.txt)或文件完整路径(例如
exampledir/exampleobject.txt)的形式实现将数据上传到当前Bucket或Bucket中的指定目录。
// data对象可以自定义为file对象、Blob数据或者OSS Buffer。
const result = client.put(`/test/${new Date().getTime()+file.name}`, file.raw||file);
return result;
}
/*
删除OSS图片方法
params:config,objKey
config:oss 相关配置参数
ObjKey: 上传文件成功后,OSS返回的name 根据这个去删除
*/
export function delImg(config, objKey) {
const client = new OSS({
// yourRegion填写Bucket所在地域。以华东1(杭州)为例,Region填写为oss-cn-hangzhou。
region: config.region,
// 从STS服务获取的临时访问密钥(AccessKey ID和AccessKey Secret)。
accessKeyId: config.osskeyId,
accessKeySecret: config.osskeySecret,
// 填写Bucket名称。
bucket: config.ossBucket
});
const result = client.delete(objKey);
return result;
}
3.引入上传组件,编写页面代码
<template>
<div id="app" v-viewer="options">
<el-upload
action="#"
:class="{ hideUploadBtn: hide }"
:file-list="fileList"
:limit="limitCount"
list-type="picture-card"
:http-request="upload"
:before-upload="beforeUploadFile"
:on-success="handleSuccess"
>
<i slot="default" class="el-icon-plus"></i>
<div slot="file" slot-scope="{ file }" style="position:relative">
<img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
<span class="el-upload-list__item-delete" @click="handleRemove(file)">
<i class="el-icon-delete"></i>
</span>
</div>
</el-upload>
</div>
</template>
<script>
//这里可以导入其他文件(比如:组件,工具js,第三方插件js,json文件,图片文件等等)
//例如:import 《组件名称》 from '《组件路径》';
import { uploadImg, delImg } from "./untils/uploadAndDeleteOss";
export default {
//import引入的组件需要注入到对象中才能使用
components: {},
data() {
//这里存放数据
return {
options:{
inline:false,
}, // viewer 图片查看器配置
fileList: [], // 文件列表
limitCount: 5, // 最大上传数
hide: false, // 是否隐藏上传按钮
maxSize: 5 * 1024 * 1024, // 单张图片最大质量
ossConfig: {
region:"your region",
ossBucket: "your bucket",
osskeyId: "your oss keyId",
osskeySecret: "your oss keySecret",
}, // oss配置参数
imgOssList:[], // 图片上传到OSS的路径集合
imgOssName:[], // 图片上传到OSS的名字集合 删除图片时用
fileNameList:[],// 图片在本地的名字集合
};
},
//监听属性 类似于data概念
computed: {},
//监控data中的数据变化
watch: {},
//方法集合
methods: {
// 自定义上传图片
async upload(file) {
try {
// 上传图片成功返回值
let imgObj = await uploadImg(this.ossConfig, file.file);
this.imgOssName.push(imgObj.name);
this.fileNameList.push(file.file.name);
if (imgObj.url) {
this.imgOssList.push(imgObj.url);
}
} catch (err) {
this.$message({
type: "error",
message: "上传失败,请稍后再试",
});
console.log(err);
}
},
// 文件上传前钩子
beforeUploadFile(file) {
return new Promise((resolve, reject) => {
if (file.size > this.maxSize) {
this.$message({
type: "error",
message: "单张支付凭证不能大于5M",
});
return reject(false);
} else {
return resolve(true);
}
});
},
// 文件上传成功钩子
handleSuccess(res, file, fileList) {
this.hide = fileList.length >= this.limitCount;
this.fileList = fileList;
},
// 删除图片钩子
handleRemove(file) {
// 获取点击删除图片的索引 并删除在本地的路径和oss路径
const index = this.fileNameList.indexOf(file.name);
this.fileList.splice(index, 1);
this.imgOssList.splice(index, 1);
this.hide = this.fileList.length >= this.limitCount;
delImg(this.ossConfig, this.imgOssName[index]);
},
},
//生命周期 - 创建完成(可以访问当前this实例)
created() {},
//生命周期 - 挂载完成(可以访问DOM元素)
mounted() {},
beforeCreate() {}, //生命周期 - 创建之前
beforeMount() {}, //生命周期 - 挂载之前
beforeUpdate() {}, //生命周期 - 更新之前
updated() {}, //生命周期 - 更新之后
beforeDestroy() {}, //生命周期 - 销毁之前
destroyed() {}, //生命周期 - 销毁完成
activated() {}, //如果页面有keep-alive缓存功能,这个函数会触发
};
</script>
<style scoped>
.el-upload-list__item-delete{
display: block;
font-size: 20px;
}
</style>
注意:
1.elemenui upload组件 如果关闭选择文件后自动上传,就不会触发before-upload钩子。
2.在before-upload钩子里面返回false依然会on-change钩子,所以这里采用http-request来覆盖默认的上传行为,实现自定义上传。
3.上面代码都是从upload组件官方文档复制过来做了一些适应业务上的修改,所以具体情况具体分析。
总结
这只是一个简单的前端上传OSS的实现,更多功能和实现方法可以参考OSS官方文档。需要注意的就是OSS一些配置和上传组件钩子函数的使用。