iview框架自带了upload上传组件,但是感觉:default-file-list
属性用起来比较麻烦,自己改写了一下。用uploadList来展示上传的图片,外部传进来的图片就用urlList,然后监听urlList,有数据变化就更新uploadList,初始化的时候也把urlList的值作为uploadList的初始值。
要注意的是上传成功后抛出uploadList,我在父组件处又更新了值
onUploadChange (data) {
this.formValidate.floorImgsList[data.index].imgUrl = data.list[0]
},
这导致传入uploader组件的props值被改变了,我在父组件传值给子组件(image-uploader)的时候又把这个url值传给了子组件
<image-uploader
@upload-change="onUploadChange"
:isDisEdit="isDisEdit"
:remark="index"
:urlList="[formValidate.floorImgsList[index].imgUrl]"
>
</image-uploader>
实际意义上变成了双向流动的数据,又触发了watch监听,刚开始做的时候没有注意到这一点,觉得奇怪怎么upladList的值连续变了2次。
做完这些之后,我觉得或许用原来的upload组件也可以实现,无非就是组装一下defaultList...
完整代码为: /imageUploader.vue
<template>
<div class="">
<div class="" style="display:flex;">
<div class="upload-list" v-for="(item,index) in uploadList">
<img :src="item">
<div class="upload-list-cover">
<Icon type="ios-eye-outline" @click.native="handleView(item)"></Icon>
<Icon type="ios-trash-outline" v-if="!isDisEdit" @click.native="handleRemove(index)"></Icon>
</div>
</div>
<div v-show="loading" class="spin-container">
<Spin fix></Spin>
</div>
<Upload
ref="upload"
type="drag"
v-show="this.uploadList.length < this.size && !isDisEdit"
:show-upload-list="false"
:action="uploadUrl"
:on-success="handleUploadSuccess"
:on-error="handleUploadError"
:format="['jpg','jpeg','png','bmp', 'gif']"
:max-size="5120"
:on-format-error="handleFormatError"
:on-exceeded-size="handleMaxSize"
:before-upload="handleBeforeUpload"
style="display: inline-block;width:58px;"
>
<div style="width: 58px;height:58px;line-height: 58px;">
<Icon type="ios-camera" size="20"></Icon>
</div>
</Upload>
</div>
<Modal title="图片" v-model="visible">
<img :src="imgSrc" v-if="visible" style="width: 100%">
</Modal>
</div>
</template>
<script>
import { uploadUrl } from '@/view/appDeploy/utils'
export default {
name: 'image-uploader',
props: {
size: {
type: Number,
default: 1
},
isDisEdit: {
type: Boolean,
default: false
},
remark: {
type: Number,
default: 0
},
urlList: {
type: Array,
default: () => {
return []
}
}
},
data () {
return {
uploadUrl: uploadUrl,
visible: false,
loading: false,
uploadList: this.urlList.filter(i=>!!i)
}
},
watch: {
urlList(newval,oldval) {
this.uploadList = this.urlList.filter(i => !!i)
}
},
methods: {
handleView (imgSrc) {
this.imgSrc = imgSrc;
this.visible = true;
},
handleRemove (index) {
this.uploadList.splice(index,1)
this.$emit('upload-change',{list: this.uploadList, index:this.remark})
},
handleUploadSuccess(res, file, list) {
this.loading = false
this.uploadList.push(res.data)
this.$emit('upload-change',{list: this.uploadList, index:this.remark})
},
handleUploadError(res, file, list) {
this.loading = false
console.log('handleUploadError', res, file, list)
},
handleFormatError(file) {
this.$Notice.warning({
title: '格式错误',
desc: file.name + ' 格式不支持, 请上传bmp,jpg,png,gif格式图片'
});
},
handleMaxSize (file) {
this.$Notice.warning({
title: '文件大小超出范围',
desc: file.name + ' 文件太大了, 请不要超出5M'
});
},
handleBeforeUpload () {
const check = this.uploadList.length < this.size;
if (!check) {
this.$Notice.warning({
title: `只能上传 ${this.size} 张图片`
});
}else {
this.loading = true
}
return check;
}
}
}
</script>
<style lang="css" scoped>
.upload-list{
display: inline-block;
width: 60px;
height: 60px;
text-align: center;
line-height: 60px;
border: 1px solid transparent;
border-radius: 4px;
overflow: hidden;
background: #fff;
position: relative;
box-shadow: 0 1px 1px rgba(0,0,0,.2);
margin-right: 4px;
}
.upload-list img{
width: 100%;
height: 100%;
}
.upload-list-cover{
display: none;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0,0,0,.6);
}
.upload-list:hover .upload-list-cover{
display: block;
}
.upload-list-cover i{
color: #fff;
font-size: 20px;
cursor: pointer;
margin: 0 2px;
}
.spin-container{
display: inline-block;
width: 60px;
height: 60px;
position: relative;
border: 1px solid #eee;
}
</style>