组件代码
<template>
<div>
<co-upload
ref="upload"
class="image-edit"
name="file"
:show-file-list="showFileList"
:list-type="listType"
:file-list="fileList"
:action="action"
:data="data"
:limit="limit"
:before-upload="handleBeforeUpload"
:on-success="handleUploadSuccess"
:on-error="handleUploadError"
:on-progress="handleProgress"
:on-change="handleChange"
:on-preview="handlePictureCardPreview"
:on-remove="handleRemove"
>
<slot>
<!-- <el-button size="small" type="primary">点击上传</el-button> -->
<i class="co-icon-add" />
</slot>
<co-progress v-if="status==='uploading'" :percentage="progress" />
<slot name="tip">
<p slot="tip" class="tip">
<span v-if="rules.width||rules.height" class="tip-item">{{ `宽高限制:${rules.width}x${rules.height} ` }}</span>
<span v-if="rules.fileSize" class="tip-item">{{ `大小限制:${fileSizeParse} ` }}</span>
<span v-if="rules.extensions" class="tip-item">{{ `格式限制:${rules.extensions} ` }}</span>
</p>
</slot>
</co-upload>
<co-dialog :visible.sync="dialogVisible">
<img class="img-preview" :src="dialogImageUrl" alt="">
</co-dialog>
</div>
</template>
<script>
/**
* <upload :before-upload="beforeUpload" @success="uploadSuccess" :rules="{width:200,height:100,fileSize:100,extensions:'jpg,png'}"/>
*/
export default {
props: {
action: {
type: String,
default() {
return this.GLOBAL_SETTINGS.uploadApi
}
},
showFileList: {
type: Boolean,
default: false
},
listType: {
type: String,
default: 'text'
},
fileList: {
type: Array,
default() {
return []
}
},
data: {
type: Object,
default() {
return {
type: 'appDomain'
}
}
},
limit: {
type: Number,
default: undefined
},
beforeUpload: {
type: Function,
default() {
return () => { return true }
}
},
rules: {
type: Object,
default() {
return {
width: 0, // 图片宽
height: 0, // 图片高
fileSize: 0, // 文件大小 B
extensions: ''// 文件后缀 'jpg,png,gif'
}
}
}
},
data() {
return {
status: 'ready',
progress: 0,
dialogImageUrl: '',
dialogVisible: false
}
},
computed: {
PATH() {
return `${process.env.VUE_APP_BASE_API}/music/cms/musiccms/upload/`
},
// 自动识别文件大小单位
fileSizeParse() {
const fileSize = this.rules.fileSize
if (fileSize < 1024) {
return fileSize + 'B'
} else if (fileSize < 1024 * 1024) {
return parseInt(fileSize / 1024) + 'K'
} else if (fileSize < 1024 * 1024 * 1024) {
return parseInt(fileSize / 1024 / 1024) + 'M'
} else {
return parseInt(fileSize / 1024 / 1024 / 1024) + 'G'
}
}
},
methods: {
// 限制符合宽高
isSize(file) {
return new Promise((resolve, reject) => {
if (this.rules.width || this.rules.height) {
// 当width和height同时为 0 时不验证
const img = new Image()
var _URL = window.URL || window.webkitURL
img.onload = () => {
if (
img.width !== this.rules.width ||
img.height !== this.rules.height
) {
this.$message.error(
`上传的图片尺寸只能是${this.rules.width}x${this.rules.height}`
)
reject('不符合宽高')
} else {
resolve('符合宽高')
}
}
img.src = _URL.createObjectURL(file)
} else {
resolve('无宽高限制')
}
})
},
// 限制文件大小
isByte(file) {
const isByte = !this.rules.fileSize ? true : file.size <= this.rules.fileSize // 文件大小符合
if (!isByte) {
this.$message.error(`上传文件大小不能超过 ${this.fileSizeParse}!`)
}
return isByte
},
// 限制文件格式
isExtensions(file) {
const extensions = this.rules.extensions
if (!extensions) {
return true
} else {
const pattern = extensions.replace(/,/g, '$|\\.').replace(/\*/g, '.*') + '$'
const regexp = new RegExp(pattern, 'i')
const invalid = regexp.test(file.name)
if (!invalid) {
this.$message.error(`文件类型限制: ${this.rules.extensions}`)
}
return invalid
}
},
// 上传前
handleBeforeUpload(file) {
console.log(12312)
return new Promise((resolve, reject) => {
const Fns = [
this.isSize(file),
this.isByte(file),
this.isExtensions(file),
this.beforeUpload(file)
]
Promise.all(Fns).then(res => {
if (res.includes(false)) {
reject()
} else {
resolve()
}
}).catch(err => {
console.log('err', err)
reject()
})
})
},
clearFiles() {
this.$refs['upload'].clearFiles()
},
// 上传成功
handleUploadSuccess(res, file, fileList) {
console.log(file)
if (res.errno === 0) {
this.$emit('success', res, file, fileList)
} else {
this.$message.error(res.data.message)
}
// this.clearFiles()
},
// 上传失败
handleUploadError(err, file, fileList) {
this.$message.error(err)
this.clearFiles()
},
// 文件上传时的钩子
handleProgress(event, file, fileList) {
this.status = 'uploading'
this.progress = Math.round(event.percent)
},
// 文件状态改变时的钩子
handleChange(file, fileList) {
this.status = file.status
},
// 预览
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url
this.dialogVisible = true
},
// 移除
handleRemove(file, fileList) {
this.$emit('remove', file, fileList)
}
}
}
</script>
<style lang="scss" scoped>
.tip{
color: #999999;
font-size: 12px;
margin: 0;
&-item{
margin-right: 12px;
}
}
.img-preview{
max-width: 100%;
margin: auto;
display: block;
}
</style>
<style lang="scss">
.image-edit{
.el-upload-list__item {
.el-upload-list__item-name {
display: block;
color: #ffffff;
background: rgba(0, 0, 0, 0.3);
position: absolute;
bottom: 0;
width: 100%;
text-align: center;
.el-icon-document {
display: none;
}
}
}
}
</style>
网友评论