<template>
<div class="component-upload-image">
<el-upload
:action="uploadImgUrl"
list-type="picture-card"
:on-success="handleUploadSuccess"
:before-upload="handleBeforeUpload"
:limit="limit"
:on-error="handleUploadError"
:on-exceed="handleExceed"
name="file"
:on-remove="handleRemove"
:show-file-list="true"
:headers="headers"
:file-list="fileList"
:on-preview="handlePictureCardPreview"
:on-progress="handleOnProgress"
:class="{ hide: this.fileList.length >= this.limit }"
:multiple="isMultiple"
>
<i class="el-icon-plus"></i>
<p class="photo-text">点击上传</p>
</el-upload>
<!-- 上传提示 -->
<div class="el-upload__tip" slot="tip" v-if="showTip">
请上传
<template v-if="fileSize">
大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b>
</template>
<template v-if="fileType">
格式为 <b style="color: #f56c6c">{{ fileType.join('/') }}</b>
</template>
的文件
</div>
<!-- 预览 -->
<el-dialog :visible.sync="dialogVisible" width="800" append-to-body custom-class="dialog-preview">
<template #title>
<div class="header">
<span>预览</span>
</div>
</template>
<img :src="dialogImageUrl" />
</el-dialog>
</div>
</template>
<script>
import { getToken } from '@/utils/auth'
import { cloneDeep } from 'lodash'
export default {
name: 'ImageUpload',
props: {
value: [String, Object, Array],
// 图片数量限制
limit: {
type: Number,
default: 5,
},
// 大小限制(MB)
fileSize: {
type: Number,
default: 5,
},
// 文件类型, 例如['png', 'jpg', 'jpeg']
fileType: {
type: Array,
default: () => ['png', 'jpg', 'jpeg'],
},
// 是否显示提示
isShowTip: {
type: Boolean,
default: true,
},
// 是否多选
isMultiple: {
type: Boolean,
default: true,
},
},
data() {
return {
dialogImageUrl: '',
dialogVisible: false,
hideUpload: false,
baseUrl: process.env.VUE_APP_BASE_API,
uploadImgUrl: process.env.VUE_APP_BASE_API + '/common/upload', // 上传的图片服务器地址
headers: {
Authorization: 'Bearer ' + getToken(),
},
fileList: [],
uploadList: [],
number: 0,
isUploading: false,
}
},
watch: {
value: {
handler(val) {
if (val) {
// 首先将值转为数组
const list = Array.isArray(val) ? val : this.value.split(',')
// 然后将数组转为对象数组
this.fileList = list.map((item) => {
if (typeof item === 'string') {
if (item.indexOf(this.baseUrl) === -1) {
item = { name: this.baseUrl + item, url: this.baseUrl + item }
} else {
item = { name: item, url: item }
}
}
return item
})
} else {
this.fileList = []
return []
}
},
deep: true,
immediate: true,
},
},
computed: {
// 是否显示提示
showTip() {
return this.isShowTip && (this.fileType || this.fileSize)
},
},
methods: {
// 删除图片
handleRemove(file, fileList) {
const findex = this.fileList.map((f) => f.name).indexOf(file.name)
if (findex > -1) {
this.fileList.splice(findex, 1)
this.$emit('input', cloneDeep(this.fileList))
}
},
// 上传成功回调
handleUploadSuccess(res) {
this.isUploading = false
this.uploadList.push({ name: res.fileName, url: this.baseUrl + res.fileName })
if (this.uploadList.length === this.number) {
this.fileList = this.fileList.concat(this.uploadList)
this.uploadList = []
this.number = 0
this.$emit('input', cloneDeep(this.fileList))
}
},
// 上传前文件校验
handleBeforeUpload(file) {
let isImg = false
if (this.fileType.length) {
let fileExtension = ''
if (file.name.lastIndexOf('.') > -1) {
fileExtension = file.name.slice(file.name.lastIndexOf('.') + 1)
}
isImg = this.fileType.some((type) => {
if (file.type.indexOf(type) > -1) return true
if (fileExtension && fileExtension.indexOf(type) > -1) return true
return false
})
} else {
isImg = file.type.indexOf('image') > -1
}
if (!isImg) {
this.$message.error(`文件格式不正确, 请上传${this.fileType.join('/')}图片格式文件!`)
return false
}
if (this.fileSize) {
const isLt = file.size / 1024 / 1024 < this.fileSize
if (!isLt) {
this.$message.error(`上传头像图片大小不能超过 ${this.fileSize} MB!`)
return false
}
}
this.number++
},
// 文件个数超出
handleExceed() {
this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`)
},
// 上传失败
handleUploadError() {
this.$message({
type: 'error',
message: '上传失败',
})
this.isUploading = false
},
// 预览
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url
this.dialogVisible = true
},
// 对象转成指定字符串分隔
listToString(list, separator) {
let strs = ''
separator = separator || ','
for (let i in list) {
strs += list[i].url.replace(this.baseUrl, '') + separator
}
return strs != '' ? strs.substr(0, strs.length - 1) : ''
},
handleOnProgress(event, file, fileList) {
this.isUploading = true
},
},
}
</script>
<style scoped lang="scss">
::v-deep .el-upload--picture-card {
border-radius: 2px;
}
// .el-upload--picture-card 控制加号部分
::v-deep.hide .el-upload--picture-card {
display: none;
}
// 去掉动画效果
::v-deep .el-list-enter-active,
::v-deep .el-list-leave-active {
transition: all 0s;
}
::v-deep .el-list-enter,
.el-list-leave-active {
opacity: 0;
transform: translateY(0);
}
::v-deep .el-upload-list--picture-card .el-upload-list__item-thumbnail {
object-fit: contain;
}
// 角标颜色
::v-deep .el-upload-list--picture-card .el-upload-list__item-status-label {
background-color: #18a8dc;
}
// 已上传图片
::v-deep .el-upload-list {
line-height: 1;
.el-upload-list__item {
margin: 0 16px 16px 0;
width: 104px;
height: 104px;
border: 1px solid #e5eaec;
border-radius: 2px;
.el-progress {
width: 102px !important;
.el-progress-circle {
width: 102px !important;
height: 102px !important;
}
}
}
}
// 上传按钮
::v-deep .el-upload {
position: relative;
width: 104px;
height: 104px;
line-height: 1;
background: #f7f8fb;
.el-icon-plus {
margin-top: 29px;
margin-bottom: 8px;
font-size: 16px;
}
.photo-text {
margin: 0;
font-weight: 400;
font-size: 14px;
line-height: 22px;
text-align: center;
color: #adb1b3;
}
}
// 预览
::v-deep .dialog-preview {
overflow: hidden;
.el-dialog__header {
position: relative;
padding: 11px 24px !important;
z-index: 2;
background: #f8faff;
border-radius: 4px 4px 0 0;
text-align: left;
.header {
display: flex;
align-items: center;
font-size: 14px;
height: 22px;
line-height: 22px;
color: #00244d;
font-weight: bold;
}
.el-dialog__headerbtn {
top: 15px;
right: 24px;
}
}
.el-dialog__body {
padding: 24px;
overflow-y: auto;
img {
display: block;
max-width: 100%;
margin: 0 auto;
}
}
}
</style>
猜你喜欢
最新发布
github访问慢解决方法
2024-11-10 13:52:54
我TM终于找到工作了
2024-06-02 14:48:43
我TM服务器又被攻击了
2024-04-12 19:28:34
Jenkins使用http方式配置github项目
2024-03-19 18:10:08
CentOS安装Jenkins服务
2024-03-18 17:23:08
终于特喵的帮朋友把微信小程序第一阶段做完了
2024-03-03 19:21:25
2023年终总结
2023-12-20 21:30:52
CentOS7 安装Node.js v14
2023-11-16 09:57:36
npm 安装依赖报错 npm ERR | gyp verb
2023-08-23 15:08:39
electron-builder + vue 搭建桌面应用
2023-06-08 10:54:28