需求:
(1). 新增记录
就是正常的上传图片,因为有好多地方需要用到,有的页面需要2个上传图片
(2). 修改记录
修改这条记录的图片
分析:
因为很多地方需要用到上传图片,有的页面需要2个,因此封装一个复用的组件。
新增:上传完图片把URL传给父组件就行了
修改:需要把后端传过来的url传入子组件显示并能修改
各个属性的作用
imgNum:限制上传图片的张数。
uploadUrl:需要传入的上传图片后端的地址
defaultList:修改传入的图片url
总结:
代码还有很大的优化空间(我把后端传过来的url先处理成数组传入子组件了,造成使用组件的时候有些繁琐,其实完全可以直接把URL传入子组件进行处理,多此一举了,但是由于懒得改就先不改了)
代码:
子组件:
<template>
<div>
<div class="demo-upload-list" v-for="(item,index) in uploadList" :key="index">
<div v-if="item.status === 'finished'" style="height:100%">
<img :src="item.response?item.response.data.netUrl:''" />
<div class="demo-upload-list-cover">
<Icon type="ios-eye-outline" @click.native="handleView(item)"></Icon>
<Icon type="ios-trash-outline" @click.native="handleRemove(item)"></Icon>
</div>
</div>
<div v-else>
<Progress v-if="item.showProgress" :percent="item.percentage" hide-info></Progress>
</div>
</div>
<!-- <div class="demo-upload-list" v-if="defaultList.length>0&&defaultList[0].response.data.netUrl!=''"><img :src="defaultList[0].response.data.netUrl"></div> -->
<!-- :headers="headerObj" -->
<Upload
:ref="uploadName"
:show-upload-list="false"
:on-success="handleSuccess"
:format="['jpg','jpeg','png']"
:max-size="2048"
:on-format-error="handleFormatError"
:on-exceeded-size="handleMaxSize"
:before-upload="handleBeforeUpload"
multiple
type="drag"
:action="uploadUrl"
style="display: inline-block;width:58px;"
>
<div style="width: 58px;height:58px;line-height: 58px;">
<Icon type="md-add" size="20"></Icon>
</div>
</Upload>
<Modal title="大图" v-model="visible">
<img :src="previewPath" v-if="visible" style="width: 100%" />
</Modal>
</div>
</template>
<script>
import config from '@/config'
export default {
name: 'uploadImgMu',
props: {
uploadName: {
type: String,
default: ''
},
uploadUrl: {
type: String,
default:''
},
defaultList: {
type: Array,
default: () => []
},
imgNum: {
type: Number,
default: 5
}
},
data () {
return {
previewPath: '',
visible: false,
uploadList: []
}
},
methods: {
handleView (file) {
this.previewPath = file.response.data.netUrl
// console.log(file);
this.visible = true
},
handleRemove (file) {
const fileList = this.$refs[`${this.uploadName}`].fileList
this.$refs[`${this.uploadName}`].fileList.splice(
fileList.indexOf(file),
1
)
this.$emit('removeImg', this.uploadList)
},
handleSuccess (res, file) {
this.$emit('getImgList', this.uploadList)
},
handleFormatError (file) {
this.$Notice.warning({
title: 'The file format is incorrect',
desc: '图片格式 ' + file.name + ' 请选择正确图片格式'
})
},
handleMaxSize (file) {
this.$Notice.warning({
title: 'Exceeding file size limit',
desc: '文件' + file.name + ' 不能大于2M'
})
},
handleBeforeUpload () {
const check = this.uploadList.length < this.imgNum
if (!check) {
this.$Notice.warning({
title: '只能上传' + this.imgNum + '张图片'
})
}
return check
}
},
mounted () {
this.uploadList = this.$refs[`${this.uploadName}`].fileList
},
watch: {
defaultList: {
handler (newV, oldV) {
if (newV.length > 0) {
let arr = []
newV.map(item => {
arr.push({
response: {
data: {
netUrl: item
}
},
status: 'finished'
})
})
this.uploadList.splice(0, this.uploadList.length) // 初始化上传防止重复出现
this.uploadList.push(...arr)
} else {
this.uploadList.splice(0, this.uploadList.length)
}
},
deep: true,
immediate: true
}
}
}
</script>
<style lang="less" scoped>
.demo-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, 0.2);
margin-right: 4px;
}
.demo-upload-list img {
width: 100%;
height: 100%;
}
.demo-upload-list-cover {
display: none;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
background: rgba(0, 0, 0, 0.6);
}
.demo-upload-list:hover .demo-upload-list-cover {
display: block;
}
.demo-upload-list-cover i {
color: #fff;
font-size: 20px;
cursor: pointer;
margin: 0 2px;
}
</style>
父组件使用
先import导入然后components注册
<imgUploadMu :uploadName="'upload1'" :imgNum="3" :uploadUrl="'www.baidu.com'" :defaultList="defaultImg" @getImgList="addTrainingImgSuccess" @removeImg="trainingImgRemove">
</imgUploadMu>
data部分
defaultImg: [], // 修改进入默认的图片
method
async getUpdate (info) {
// 这里只是我从后端返回来的数据把图片的url赋值给defaultImg
//当需要修改的时候
const { data: res } = await getUpdate(info)
this.defaultImg= res.data.pic ? res.data.pic.split(',') : []
//就是这里其实可以在子组件里处理掉返回来的url
},
addTrainingImgSuccess (val) {
let arr = val.map(item => {
return item.response.data.netUrl
})
this.formItem.trainingPic = arr.join()//把子组件返回的值赋值给表单
},
// 删除图片成功
trainingImgRemove (val) {
let arr = val.map(item => {
return item.response.data.netUrl
})
this.formItem.trainingPic = arr.join()//删除表单里的图片
},