MultiUpload.vue 组件
<template>
<div>
<div tabindex="0" class="pasteArea" :class="{'active': isActive}" @paste="handlePaste" @focus="handleFocus" @blur="handleBlur">
<div class="iconPicture">
<i class="el-icon-picture iconWidth" style="color:#3670ff;font-size:28px" />
</div>
<div class="description">将截图按Ctrl+V 粘贴至此处</div>
</div>
<div class="prompt">本地图片或者多张图片请使用本地上传“+”(支持拓展名:.jpg .png .gif)</div>
<el-upload
ref="upload"
:action="uploadUrl()"
list-type="picture-card"
accept=".jpg,.jpeg,.png,.gif"
multiple
:file-list="fileList"
:on-remove="handleRemove"
:on-success="handleUploadSuccess"
:before-upload="handleBeforeUpload"
:on-preview="handlePreview"
:limit="maxCount"
:on-exceed="handleExceed"
>
<i class="el-icon-plus" />
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" :alt="dialogImageName">
</el-dialog>
</div>
</template>
<script>
import { getImageUpload } from '@/api/badFruit'
export default {
name: 'MultiUpload',
props: {
// 图片属性数组
value: {
type: Array,
default: () => []
},
// 最大上传图片数量
maxCount: {
type: Number,
default: 5
}
},
data() {
return {
fileList: [],
imagesList: [],
images: [],
dialogVisible: false,
dialogImageUrl: null,
dialogImageName: '',
isActive: false,
num: 0,
fileNum: 0
}
},
created() {
// 上传组件显示列表
this.fileList = this.value
// 图片保存数组
this.imagesList = this.value
},
methods: {
// 文件上传地址
uploadUrl() {
return getImageUpload
},
handleRemove(file, fileList) {
const list = JSON.parse(JSON.stringify(fileList))
this.imagesList = list.map(item => ({
name: item.name,
url: item.url
}))
this.$emit('input', this.imagesList)
},
handlePreview(file) {
this.dialogVisible = true
this.dialogImageUrl = file.url
this.dialogImageName = file.name
},
handleUploadSuccess(res, file) {
// console.log(res, file)
if (res.code === '200') {
const { message, path } = res.data
if (message === '图片上传成功') {
this.images.push({
name: file.name,
url: path
})
this.num++
if (this.num === this.fileNum) {
this.num = 0
this.fileNum = 0
// 这里如果 this.value.push(imageUrl) 这么写,vue会报出警告,大概意思是value作为props不应该在子组件中被修改
// 应该根据 value 得到新的值,而不能修改它,this.value.concat(imageUrl)也是可以的,concat方法返回新的数组
this.imagesList = this.imagesList.concat(this.images)
this.$emit('input', this.imagesList)
this.images = []
}
} else {
this.$message.error(message)
}
}
},
handlePaste(e) {
const items = (e.clipboardData || window.clipboardData).items
let file = null
if (!items || items.length === 0) {
this.$message.error('当前浏览器不支持粘贴本地图片,请打开图片复制后再粘贴!')
return
}
// 搜索剪切板items
for (let i = 0; i < items.length; i++) {
if (items[i].type.indexOf('image') !== -1) { // 此行代码注释掉,可以上传所有类型的文件
file = items[i].getAsFile()
break
}
}
console.log('已上传文件个数:' + this.imagesList.length)
if (file && this.imagesList.length < this.maxCount) { // 对复制黏贴的类型进行判断,若是非文件类型,比如复制黏贴的文字,则不会调用上传文件的函数
// 生成预览图
this.$refs.upload.handleStart(file)
// 提交上传
this.$refs.upload.$refs['upload-inner'].upload(file)
} else {
if (this.imagesList.length === this.maxCount) {
this.$message({
message: '最多只能上传' + this.maxCount + '张图片',
type: 'warning',
duration: 1000
})
}
}
},
handleFocus() {
this.isActive = true
},
handleBlur() {
this.isActive = false
},
handleBeforeUpload(file) {
this.fileNum++
console.log('上传个数:' + this.fileNum)
},
handleExceed(files, fileList) {
this.$message({
message: '最多只能上传' + this.maxCount + '张图片',
type: 'warning',
duration: 1000
})
}
}
}
</script>
<style scoped lang="scss">
.pasteArea {
width: 500px;
height: 80px;
border: #dfe6ec dashed 1px;
border-radius: 6px;
-webkit-border-radius: 6px;
.iconPicture {
width: 26px;
height: 26px;
position: relative;
border: #99b5ff dashed 1px;
margin: 12px auto 8px;
.iconWidth {
position: absolute;
top: 5px;
left: 5px;
z-index: 999;
}
}
.description{
color: #3670ff;
font-size: 14px;
text-align: center;
}
}
.active {
border: #3670ff dashed 1px !important;
cursor: pointer;
}
.prompt {
width: 500px;
color: #b0bcdc;
font-size: 12px;
text-align: center;
}
</style>
展示效果如下:
注意:本篇是使用action上传的地址,而不是自定义上传http-request实现上传接口,如果使用http-request 把相对应的代码改成http-request 形式。以及本篇未实现粘贴上传时进度条的展示,如果需要可自己研究(如果好了可以留言告知一下),也可以采用http-request自定义的方式实现。
如有问题欢迎留言 ^ ^