一、最终效果
二、参数配置
1、代码示例:
<t-upload
@fileList="fileList"
:showFileList="showFileList"
@showFile="showFile"
:showFileUrl="showFileUrl"
/>
2、配置参数(TUpload Attributes)继承van-uploader的属性
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
limitSize | 限制上传文件大小 | Number | 10MB |
fileType | 限制上传的文件类型 | String | .jpg,.jpeg,.png |
totalLimit | 最多上传个数限制 | Number | 5 |
showFileList | 回显文件的list(内含:url–>对应完整路径) | Array | - |
showFileUrl | 上传组件回显图片–相对路径数据(后台需要) | Array | - |
savePath | 服务器上传地址 | String | 自己的上传地址 |
3、events 事件继承van-uploader的事件
事件名 | 说明 | 返回值 |
---|---|---|
fileList | 上传成功或删除成功触发 | 返回最终上传数据 |
showFile | 回显list删除后触发 | 返回回显上传没有删除的数据 |
三、具体页面使用
<template>
<div class="initial_Judgment">
<div class="img_box">
<div class="img_title">
终判图
</div>
<t-upload
:showFileUrl="showFileUrl"
:showFileList="showFileList"
@fileList="fileList"
@showFile="showFile"
/>
</div>
</div>
</template>
<script>
export default {
name: 'initialJudgment',
data() {
return {
formData: {
images: [], //上传图片
},
showFileList: [], // 上传组件--回显内含url且是完整地址
showFileUrl: [], // 上传组件回显图片--相对路径数据
}
},
created() {
this.getFinalInfo()
},
methods: {
// 获取详情信息
async getFinalInfo() {
const res = await this.$api.getFinalInfo(this.$route.query.id)
console.log('详情数据', res)
if (res.success) {
if (res.data.finalImages.length > 0) {
this.showFileList = res.data.finalImages || []
this.showFileUrl = res.data.finalImages.map(item => item.relativeUrl)
}
}
},
// 回显数据删除触发
showFile(list) {
this.showFileUrl = list
},
// 上传成功或删除触发
fileList(list) {
this.formData.images = list
},
// 点击确认
async handlerConfirm() {
const { warehouseSpaceId, receveMethod, images } = this.formData;
const requiredFields = [
{ field: warehouseSpaceId, message: '请先选择卸货料垛' },
{ field: receveMethod, message: '请先选择收货方式' },
{ field: images.length || this.showFileUrl.length, message: '请先上传图片' }
];
const hasEmptyFields = requiredFields.some(field => !field.field);
if (hasEmptyFields) {
this.$toast(requiredFields.find(field => !field.field).message);
return;
}
let params = {
...this.formData,
}
params.images = [...this.showFileUrl, ...this.formData.images]
console.log('最终参数---图片相对路径', params.images)
// console.log('最终参数---', params)
// return
this.$dialog
.confirm({
message: '是否确认终判?'
})
.then(async () => {
const res = await this.$api.finalConfirm(params)
if (res.success) {
this.$toast.success('确认成功')
this.$router.push({ path: '/endJudgingScrapSteel' })
}
})
.catch(() => {
console.log('取消')
})
}
},
};
</script>
四、源码
<template>
<van-uploader
class="t-upload"
v-model="fileList"
v-bind="uploadAttrs"
v-on="$listeners"
:before-read="beforeRead"
:before-delete="delImg"
:after-read="afterRead"
/>
</template>
<script>
import axios from 'axios'
import { getToken } from '@/utils/auth'
export default {
name: 'TUpload',
props: {
// 限制上传文件大小默认10MB
limitSize: {
type: [Number, String],
default: 10
},
// 限制上传的文件类型
fileType: {
type: String,
default: '.jpg,.jpeg,.png'
},
// 最多上传个数限制
totalLimit: {
type: Number,
default: 5
},
// 回显文件的list(内含:url-->对应完整路径)
showFileList: {
type: Array,
default: () => {
return []
}
},
// 上传组件回显图片--相对路径数据
showFileUrl: {
type: Array,
default: () => {
return []
}
},
// 服务器上传地址
savePath: {
type: String,
default: `${process.env.VUE_APP_API_URL}/scmpda/file/upload`
},
},
data() {
return {
fileList: [],
fileUrls: [],
showUrl: this.showFileUrl
}
},
computed: {
uploadAttrs() {
return {
'max-count': this.totalLimit,
multiple: true,
...this.$attrs
}
}
},
watch: {
showFileList: {
handler(val) {
this.fileList = val
}
},
showFileUrl: {
handler(val) {
this.showUrl = val
}
}
},
methods: {
beforeRead(file) {
// console.log('上传前', file)
if (file instanceof Array) {
file.forEach(item => {
const isNotMatchType = this.fileType.indexOf('.' + item.name.slice(item.name.lastIndexOf('.') + 1).toLocaleLowerCase()) === -1
if (isNotMatchType) {
this.$toast.fail('请上传jpg或png格式的图片')
return false
}
const overSize = item.size / (1024 * 1024) > this.limitSize
if (overSize) {
this.$toast.fail(`上传文件不得大于${this.limitSize}MB`)
return false
}
})
} else {
const isNotMatchType = this.fileType.indexOf('.' + file.name.slice(file.name.lastIndexOf('.') + 1).toLocaleLowerCase()) === -1
if (isNotMatchType) {
this.$toast.fail('请上传jpg或png格式的图片')
return false
}
const overSize = file.size / (1024 * 1024) > this.limitSize
if (overSize) {
this.$toast.fail(`上传文件不得大于${this.limitSize}MB`)
return false
}
}
if (file.length >= this.totalLimit) {
this.$toast.fail(`最多上传${this.totalLimit}个文件`)
return false
}
return true
},
delImg(fileMsg) {
const delIndex = this.fileList.findIndex(item => item === fileMsg);
if (delIndex > -1) {
this.fileList.splice(delIndex, 1);
const showIndex = delIndex - this.showFileList.length;
if (fileMsg.url) {
this.showUrl.splice(showIndex, 1);
} else {
this.fileUrls.splice(showIndex, 1);
}
}
this.$emit(fileMsg.url ? 'showFile' : 'fileList', fileMsg.url ? this.showUrl : this.fileUrls);
},
afterRead(file) {
if (file instanceof Array) {
file.forEach(f => {
f.status = 'uploading'
f.message = '上传中...'
this.uploadFile(f)
})
} else {
file.status = 'uploading'
file.message = '上传中...'
this.uploadFile(file)
}
},
async uploadFile(file) {
const formDataFile = new FormData()
formDataFile.append('file', file.file)
const res = await axios({
url: this.savePath,
method: 'post',
headers: {
'Content-Type': 'multipart/form-data',
Authorization: getToken()
},
data: formDataFile
})
if (res.data.success) {
file.status = 'done'
file.message = '上传成功'
this.fileUrls.push(res.data.data)
this.$toast('图片上传成功!')
this.$emit('fileList', this.fileUrls)
} else {
file.status = 'failed'
file.message = '上传失败'
this.$toast('照片上传失败,请重新上传!')
}
}
}
}
</script>
相关文章
基于ElementUi再次封装基础组件文档
基于ant-design-vue再次封装基础组件文档
vue3+ts基于Element-plus再次封装基础组件文档