1、新建组件FileUpload.vue
<template>
<div>
<el-upload
:action="action"
:file-list="fileList"
list-type="picture-card"
:http-request="uploadHttp"
:headers="headers"
:limit="limit"
:accept="accept"
:class="hideUpload || uploading ? 'hideUpload' : ''"
:on-error="handleError"
:before-upload="beforeUpload"
:on-success="handleSuccess"
>
<i slot="default" class="el-icon-plus"></i>
<div slot="file" slot-scope="{ file }">
<img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
<span
v-if="file.status === 'success'"
class="el-upload-list__item-actions"
>
<span
v-if="preview"
class="el-upload-list__item-preview"
@click="handleImgPreview(file)"
>
<i class="el-icon-zoom-in"></i>
</span>
<span
v-if="download"
class="el-upload-list__item-delete"
@click="handleDownload(file)"
>
<i class="el-icon-download"></i>
</span>
<span
v-if="deleted"
class="el-upload-list__item-delete"
@click="handleRemove(file)"
>
<i class="el-icon-delete"></i>
</span>
</span>
<span
v-else
:class="[
uploading ? 'uploading' : '',
'el-upload-list__item-actions',
]"
>
<i class="el-icon-loading" /><i style="font-size: 14px">上传中</i>
</span>
</div>
</el-upload>
<el-dialog :visible.sync="previewVisible">
<img width="100%" :src="previewImgUrl" alt="" />
</el-dialog>
</div>
</template>
<script>
import OSS from 'ali-oss'
export default {
name: 'FileUpload',
model: {
prop: 'list',
event: 'change',
},
props: {
// 上传的地址
action: {
type: String,
default: '#',
},
// 文件列表默认值, 格式[url1, url2]
list: {
type: Array,
default: () => [],
},
// 设置上传的请求头部
headers: {
type: Object,
default: () => {
return {}
},
},
// 上传文件大小限制, 默认0 不限制,单位M
size: {
type: [Number, String],
default: 0,
},
// 文件上传格式, 默认jpeg, png,jpg
accept: {
type: String,
default: 'image/jpeg,image/png',
},
// 是否显示删除操作按钮
deleted: {
type: Boolean,
default: true,
},
// 是否显示预览操作按钮
preview: {
type: Boolean,
default: true,
},
// 是否显示下载操作按钮
download: {
type: Boolean,
default: true,
},
// 上传文件个数限制,默认0 不限制
limit: {
type: [Number, String],
default: 0,
},
},
data() {
return {
fileList: [], // 默认文件列表
hideUpload: false, // 超出限制掩藏上传按钮
uploading: false, // 是否上传中,上传时隐藏上传按钮
previewImgUrl: '', // 预览图片地址
previewVisible: false, // 是否显示预览
}
},
mounted() {
const { list } = this
this.fileList = list.map((url) => {
return { url }
})
this.handleChange()
},
methods: {
// 自定义上传接口,如阿里oss, 不使用去掉最上面的 http-request
uploadHttp({ file }) {
// 后台sts方式 获取临时上传参数region, accessKeyId, accessKeySecret, stsToken, bucket
const { region, accessKeyId, accessKeySecret, stsToken, bucket } = {} // 后台请求
const client = new OSS({
region,
accessKeyId,
accessKeySecret,
stsToken,
bucket,
})
const path = `image/${Date.now()/${file.name}}` // 定义上传路径, 上传路径=文件夹路径+文件名称
client
.put(path, file)
.then(({ name }) => {
const { fileList } = this
const url = `http://${bucket}.${region}.aliyuncs.com/${name}`
this.fileList = fileList.push({ url })
this.handleChange()
})
.catch((e) => {
this.$message.error('上传失败!')
this.handleChange()
})
},
// 上传前文件大小判断
beforeUpload(file) {
const { size } = this
const overSize = size > 0 && file.size < 1024 * 1024 * size
if (!overSize) this.$message.error(`上传文件大小不能超过 ${size}MB!`)
this.uploading = overSize // 是否上传中
return overSize
},
// 上传出错返回
handleError(event, file, fileList) {
console.log(event, file, fileList, 'error')
this.$message.error('服务出错,上传失败!')
this.handleChange()
},
// 默认上传接口成功返回
handleSuccess(res, file, list) {
// 根据res上传接口返回结果判断是否上传成功
//注意size为1时 直接赋值 成功 this.fileList =[{url: url地址}] 失败 this.fileList = []
//上传大于1的下面处理方式
// 上传失败处理
// this.fileList = list.splice(fileList.length - 1, 1)
// this.$message.error('上传失败!')
// // 上传成功处理, 注意list数组返回值最后一个对象为本地上传的url地址,不是线上地址
this.fileList.push({url: 上传成功返回的url地址})
this.handleChange()
},
// 删除图片
handleRemove(file) {
const { fileList } = this
this.fileList = fileList.filter((item) => item.uid !== file.uid)
this.handleChange()
},
// 图片预览
handleImgPreview(file) {
this.previewImgUrl = file.url
this.previewVisible = true
},
handleChange(file, list) {
const { limit, fileList } = this
if (limit > 0 && fileList.length >= limit) this.hideUpload = true
else this.hideUpload = false
this.uploading = false
const fileArr = []
fileList.forEach((item) => fileArr.push(item.url))
console.log(fileArr)
this.$emit('change', fileArr)
},
handleDownload(file) {
const a = document.createElement('a')
a.href = file.url
a.click() // 模拟点击事件,实现图片文件的同源下载
},
},
}
</script>
<style>
.hideUpload .el-upload--picture-card {
display: none;
}
.el-upload-list--picture-card .uploading.el-upload-list__item-actions {
opacity: 1;
}
/*添加、删除文件时去掉动画过渡*/
.el-upload-list__item {
transition: none !important;
}
</style>
2、使用
<FileUpload
v-model="fileList"
action="#"
:size="size"
:accept="accept"
:limit="limit"
/>
import FileUpload from '@/components/FileUpload'
export default {
components: { FileUpload },
data() {
return {
fileList: [],
limit: 2,
size: 2,
accept: 'image/jpeg,image/png',
}
},
}
3、效果