自己封装el-upload组件,可直接使用,持续更新完善中
子组件:
//点击看大图
上传文件
{{ fileName }}
下面贴上js代码
export default {
props: {
//是否展示上传时的loading
showLoading: {
type: Boolean,
default: true,
},
maxLength: {
// 可上传的最大数量
type: Number,
default: 1,
},
// 图片集合
filesList: {
type: Array,
default: () => [],
},
// 上传按钮样式类型
type: {
type: Number,
default: 0,
},
// 是否禁用
disabled: {
type: Boolean,
default: false,
},
// 是否可删除图片
canDelete: {
type: Boolean,
default: true,
},
// 是否展示图片
showImages: {
type: Boolean,
default: true,
},
},
data() {
return {
uploadUrl: `${baseUrl}/common/uploadFile`, //上传的接口
headers: { Authorization: localStorage.getItem('token') },
upImgList: [],
percentage: 0,
fileName: '',
status: null,
progressShow: false,
showBigImg: '',
dialogVisible: false,
tempArr: [],
startImgIndex: '', //拖动前图片index
endImgIndex: '', // 结束拖动的index
cancelUpload: false,
}
},
mounted() {
this.upImgList = this.filesList
},
watch: {
filesList(val) {
this.upImgList = val
},
},
methods: {
// 拖动开始
dragstartEventImg($event, index) {
this.startImgIndex = index
},
// 拖动时
dragenterEventImg($event, index) {
this.endImgIndex = index
},
// 拖动结束
dragendEventImg($event, index) {
const currRow = this.upImgList.splice(this.startImgIndex, 1)[0]
this.upImgList.splice(this.endImgIndex, 0, currRow)
this.$emit('getImgList', this.upImgList)
},
// 放置
dragoverEventImg(e) {
e.preventDefault()
},
// 查看大图
lookBigImg(url) {
this.showBigImg = url
this.dialogVisible = true
},
format(percentage) {
return percentage === 100 ? '99%' : `${percentage}%` //防止到100时后端处理要时间,会卡在100一小段时间,优化体验
},
// 超出限制
onExceed() {
this.$message.error('选择的文件超出个数限制')
},
// 删除图片
deleteImg(item) {
for (let i = 0; i < this.upImgList.length; i++) {
if (this.upImgList[i].url === item) {
this.upImgList.splice(i, 1) // 将使后面的元素依次前移,数组长度减1
i-- // 如果不减,将漏掉一个元素
}
}
this.$emit('getImgList', this.upImgList)
},
// 上传时的钩子
progress(event, file, fileList) {
this.progressShow = true
this.percentage = Math.ceil(event.percent)
if (this.cancelUpload) {
this.$refs.imageUpload.abort()
this.$message.error('文件已取消上传')
this.upImgList = this.upImgList.filter((item) => {
return item.url
})
this.$emit('getImgList', this.upImgList)
this.progressShow = false
}
},
// 上传失败
onError(err, file, fileList) {
this.upImgList.forEach((element, index) => {
if (element.uid === file.uid) {
this.upImgList.splice(index, 1) // 上传失败删除该记录
this.$message.error('文件上传失败')
this.$emit('getImgList', this.upImgList)
this.progressShow = false
this.status = null
this.percentage = 0
this.fileName = ''
}
})
},
//图片上传前
beforeUploadImg(file) {
this.cancelUpload = false
let allowType = ['image/png', 'image/jpeg']
if (allowType.indexOf(file.type) === -1) {
this.$message.error('上传图片只能是 JPG、PNG 格式!')
return false
}
if (file.size / 1024 / 1024 >= 3) {
this.$message.error('只能上传小于3M的图片!')
return false
}
this.fileName = file.name
this.objAddItem(this.upImgList, file)
},
// 图片上传成功
uploadImg(response, file, fileList) {
let num = 0
this.upImgList.forEach((item, index) => {
if (item.uid === file.uid) {
let ele = {
uid: item.uid,
url: response.data.fileUrl,
}
this.$set(this.upImgList, index, ele)
}
if (item.url === '') {
num++
}
})
this.$emit('getImgList', this.upImgList)
if (num === 1) {
this.progressShow = false //进度条消失
this.status = null
this.percentage = 0
this.fileName = ''
}
},
objAddItem(tempArr, file) {
const tempObj = {
uid: file.uid, // uid用于辨别文件
url: '',
}
tempArr.push(tempObj)
},
},
}
样式部分
.imgList {
display: flex;
flex-wrap: wrap;
div {
.img {
position: relative;
img {
cursor: pointer;
width: 64px;
height: 64px;
display: inline-block;
}
width: 64px;
height: 64px;
display: inline-block;
margin-right: 8px;
.el-icon-error {
font-size: 16px;
position: absolute;
right: -8px;
top: -8px;
color: red;
}
}
}
}
.normal {
&:hover {
color: #5d8eff !important ;
background-color: #fff !important ;
border-color: #5d8eff !important ;
}
&::before {
content: '';
background-image: url('@/assets/images/upload2.png');
background-size: 14px 14px;
display: inline-block;
width: 14px;
height: 14px;
transform: translateY(2px);
margin-right: 6px;
}
}
.uploadBtn {
width: 64px;
height: 64px;
background: #f7f8fa;
border: 1px solid #ebebe8;
position: relative;
i {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #bebec5;
font-size: 24px;
}
}
.uploading {
display: flex;
width: 162px;
margin-left: 8px;
margin-top: 28px;
.left {
margin-right: 8px;
i {
display: inline-block;
width: 14px;
height: 14px;
color: #000;
}
}
.right {
width: 140px;
.right-top {
display: flex;
justify-content: space-between;
span {
height: 22px;
font-size: 14px;
font-weight: 400;
color: rgba(0, 0, 0, 0.45);
line-height: 22px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
width: 130px;
}
}
}
.el-icon-close {
line-height: 22px;
}
}
.disabledStyle {
cursor: not-allowed;
}
父组件使用:
其他功能可根据子组件的props来设置
|