今天使用
upload
组件总是回显有问题,不是回显有问题,就是上传不上去,总结了一下,写了个组件,以后就不会出现类似问题了
遇到的问题及解决方案
- upload组件上传回调只有一次
uploading
状态回调(正常是三次)
解决方案

官网中确实说明有三种回调,uploading(上传中)、done(完成)、error(错误),可是为什么只有一次呢,后来发现:如果修改回返回值fileList,他只会有一次回调(只有uploading)
,猜测是这个状态需要返回给组件,才能进行下一步(done)
- 列表中文件回显时,会只显示第一次打开的内容(回显问题)
解决方案

原因在与这两个api,分别说明:
defaultFileList:使用这个的时候,只会显示第一次传入的内容,因为组件第二次加载就不会触发了,如果数据改变也不会引起页面的变化
fileList: 这是一个受控的组件,他可以根据传入数据改变页面,所以这里我们只用fileList
- 文件的校验,包括大小,格式
解决方案
一开始只返回true,false,但是总是不起作用,后来试了一下promise就可以了...
组件示例,分为文件和图片
文件
<!--------------------使用方法--start-->
<b-upload
:defaultFileList="defaultFileList"
@change="handleChange"
/>
handleChange (data) {
this.defaultFileList = data
},
<!--------------------使用方法--end-->
<template>
<a-upload
:action="actionUrl"
:beforeUpload="beforeFileUpload"
:disabled="disabled"
:fileList="fileList"
:headers="headers"
:multiple="multiple"
@change="handleChange"
>
<a-button>
<a-icon type="upload"/>
上传
</a-button>
</a-upload>
</template>
<script>
export default {
name: 'BUpload',
props: {
defaultFileList: {
type: Array,
default: function () {
return []
},
required: true
},
fileTypeList: {
type: Array,
default: function () {
return []
},
required: false
},
limitSize: {
type: Number,
default: 2,
required: false
},
actionUrl: {
type: String,
default: '/api/storage/upload',
required: false
},
multiple: {
type: Boolean,
default: false,
required: false
},
disabled: {
type: Boolean,
default: false,
required: false
}
},
watch: {
defaultFileList (newVal) {
this.fileList = newVal
}
},
data () {
return {
headers: {
authorization: ''
},
fileList: []
}
},
created () {
this.fileList = this.defaultFileList
this.headers.authorization = 'Bearer ' + this.$store.state.user.token
},
methods: {
// ---------------------------------------------file--start
handleChange (info) {
if (info.file.status === 'done') {
this.$message.success('文件上传成功!')
}
let fileList = [...info.fileList]
fileList = fileList.map(file => {
if (file.response) {
const res = file.response.data
file.name = res.filename
file.url = res.url
}
return file
})
this.fileList = fileList
this.$emit('change', this.fileList)
},
beforeFileUpload (file) {
return new Promise((resolve, reject) => {
if (!this.fileTypeList) {
const index = this.fileTypeList.indexOf(file.type)
if (index > 0) {
this.$message.error(`您只能上传${this.fileTypeList[index]}文件`)
}
}
const limitSize = file.size / 1024 / 1024 < this.limitSize
if (!limitSize) {
this.$message.error(`文件大小不能大于${this.limitSize}MB`)
return reject(new Error(`文件大小不能大于${this.limitSize}MB`))
}
this.$message.info('文件正在上传中...')
return resolve(true)
})
}
// ---------------------------------------------file--end
}
}
</script>
<style scoped>
</style>
图片
<!--------------------使用方法--start-->
<b-upload-image
:defaultImageList="defaultImageList"
:disabled="false"
:multiple="true"
@change="handleImageChange"
/>
handleImageChange (data) {
this.defaultImageList = data
},
<!--------------------使用方法--end-->
<template>
<div>
<a-upload
:action="actionUrl"
:beforeUpload="beforeImageUpload"
:disabled="disabled"
:fileList="imageList"
:headers="headers"
:multiple="multiple"
@change="handleImageChange"
@preview="handleImagePreview"
listType="picture-card"
>
<div v-if="defaultImageList.length < limitNum">
<a-icon :type="imageLoading ? 'loading' : 'plus'"/>
<div class="ant-upload-text">上传</div>
</div>
</a-upload>
<a-modal :footer="null" :visible="previewVisible" @cancel="handleImageCancel">
<img :src="previewImage" alt="example" style="width: 100%"/>
</a-modal>
</div>
</template>
<script>
export default {
name: 'BUploadImage',
props: {
defaultImageList: {
type: Array,
default: function () {
return []
},
required: true
},
fileTypeList: {
type: Array,
default: function () {
return []
},
required: false
},
limitSize: {
type: Number,
default: 2,
required: false
},
limitNum: {
type: Number,
default: 3,
required: false
},
actionUrl: {
type: String,
default: '/api/storage/upload',
required: false
},
multiple: {
type: Boolean,
default: false,
required: false
},
disabled: {
type: Boolean,
default: false,
required: false
}
},
watch: {
defaultImageList (newVal) {
this.imageList = newVal
}
},
data () {
return {
headers: {
authorization: ''
},
imageLoading: false,
previewVisible: false,
previewImage: '',
imageList: []
}
},
created () {
this.imageList = this.defaultImageList
this.headers.authorization = 'Bearer ' + this.$store.state.user.token
},
methods: {
// ---------------------------------------------img--start
handleImageChange (info) {
if (info.file.status === 'done') {
this.$message.success('文件上传成功!')
}
let fileList = [...info.fileList]
fileList = fileList.map(file => {
if (file.response) {
const res = file.response.data
file.name = res.filename
file.url = res.url
}
return file
})
this.imageList = fileList
this.$emit('change', this.imageList)
},
beforeImageUpload (file) {
return new Promise((resolve, reject) => {
if (!this.fileTypeList) {
const index = this.fileTypeList.indexOf(file.type)
if (index > 0) {
this.$message.error(`您只能上传${this.fileTypeList[index]}文件`)
}
}
const limitSize = file.size / 1024 / 1024 < this.limitSize
if (!limitSize) {
this.$message.error(`文件大小不能大于${this.limitSize}MB`)
return reject(new Error(`文件大小不能大于${this.limitSize}MB`))
}
this.$message.info('文件正在上传中...')
return resolve(true)
})
},
handleImagePreview (file) {
this.previewImage = file.url || file.thumbUrl
this.previewVisible = true
},
handleImageCancel () {
this.previewVisible = false
}
// ---------------------------------------------img--end
}
}
</script>
<style scoped>
</style>
网友评论