H5实现图片上传

H5实现图片上传

关于H5实现图片上传的需求中,下面记录的是使用该插件如何实现图片上传,过程中遇到的问题以及如何解决的。记录的目的一方面提醒自己不要再犯此类错误,一方面督促自己写博客。遇到问题记录下来,每天进步一点点!

首先我遇到的需求是一个提交表单,表单中包含图片上传的功能。使用的是vant ui 的upload插件,需求是可以多选图片,最多可上传三张,但是upload组件的多选属性multiple部分安卓手机不支持,也就改成单选了。

图片先上传upload组件的使用如下:

<van-uploader v-model="imageList" :beforeDelete="beforeDelete" @oversize="oversize"  :afterRead="afterRead" :max-count="3" :max-size="1024 * 1024 * 5" :preview-size="preViewSize">
   <van-button icon="plus" :style="uploadStyle"></van-button>
</van-uploader>

```javascript
export default {
	data () {
		return {
      		imageList: [], // 图片预览列表
      		uploadStyle: {
        		width: '100px',
        		height: '100px'
      		},
			preViewSize: 100, // 图片预览尺寸
		}
	},
	mounted () {
    	// 上传文件样式设置, 需求是最多可上传三张图片,针对不同机型对图片展示的宽度尺寸做适配
    	let deviceWidth = window.innerWidth
    	if (deviceWidth > 414) {
      	deviceWidth = 414
    	}
    	let uploadWidth = deviceWidth - 16 * 2 - 10 * 2
    	let width = uploadWidth / 3 - 8
   	 	this.preViewSize = width
    	this.uploadStyle = {
      		width: `${width}px`,
      		height: `${width}px`
    	}
  	},
  	methods: {
  	// 图片超出大小
    oversize (file, detail) {
      Notify({ type: 'warning', message: '图片不能超过5M~' })
    },
    // 删除图片
    beforeDelete (file, detail) {
      this.imageList.splice(detail.index, 1)
    },
    // 图片上传后,获取返回的参数,在提交时当做参数传递给后台,uploadImgList是图片上传后返回的图				片信息列表
    afterRead (file, detail) {
      // 上传图
      file.status = 'uploading'
      file.message = '上传中'
      // 调用上传方法
      this.upload(file.file).then(res => {
      // 根据index来判断是哪个图片,这种导致后面删除前一张,index变化了,出现问题
      
        file.url = res.data.downloadUrl
        file.status = 'done'
        file.message = ''
      }).catch(rej => {
        let item = {
          status: 'failed'
        }
        file.status = 'failed'
        file.message = '上传失败'

      })
    },
    // 上传图片接口
    upload (file) {
      return new Promise((resolve, reject) => {
        let formdata = new FormData()
        formdata.append('filecontent', file)
        $.ajax({
          url: this.uploadUrl,
          data: formdata,
          type: 'post',
          headers: {
            // 添加一个mock 人,手机端之前没有加,导致失败了,根据自己的项目来判断是否要加
          },
          processData: false,
          contentType: false,
          success (res) {
            res.data.name = file.name
            resolve(res)
          },
          error (res) {
            reject(res)
          }
        })
      })
    },
  }
}

上面代码是根据index来删除和上传添加的,其实这样是不准确的,index不能作为唯一性标识。如果操作顺序为:第一张上传成功,第二张正在上传,删除第一张,此时index就变了,而afterRead方法中detail.index,为删除前的index,这样就导致不准确了。

解决办法:上传前添加唯一标识符,代码如下

// 添加唯一标识的方法
function onlymd() {
  function s4 () {
    return Math.floor((1 + Math.random()) * 0x10000)
        .toString(16)
        .substring(1)
  }

  return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
    s4() + '-' + s4() + s4() + s4()
}
// afterRead方法和beforeDelete更改如下
// 删除图片
    beforeDelete (file, detail) {
    // 根据唯一标识来删除图片
      this.imageList.forEach(item => {
      	if (item.md === file.md) {
      		this.imageList.splice(detail.index, 1)
      	}
      }) 
    },
    // 图片上传后,获取返回的参数,在提交时当做参数传递给后台,uploadImgList是图片上传后返回的图				片信息列表
    afterRead (file, detail) {
    // 添加唯一标识
    file.md = this.onlymd()
      // 上传图
      file.status = 'uploading'
      file.message = '上传中'
      // 调用上传方法
      this.upload(file.file).then(res => {
      // 根据唯一标识来判断是哪张图片的返回结果
      this.imageList.forEach(item => {
      	if (item.md === file.md) {
      		//找到图片进行数据处理
      	}
      }) 
   	
        file.status = 'done'
        file.message = ''
      }).catch(rej => {
        let item = {
          status: 'failed'
        }
        // 由于删除的时候uploadImgList和imageList 的index要相对应,所以即使失败了,也要添加一项进去,这部之前没做处理导致删除项对应不上
        file.status = 'failed'
        file.message = '上传失败'
        this.uploadImgList.push(item)
      })
    },

最后是提交的时候,之前出现问题图片没有上传完成,就点了提交按钮,这就导致了,提交时图片的参数没有携带上去,出现错误。
解决办法
图片上传时不允许提交,提交按钮置于不可操作的状态
在提交时对就是对uploadImageList参数做处理,用的是数组的filter方法,把status为failed的过滤出去,这里就不贴代码了。

总结,注意的点:

1.一定要确保图片上传完成后,再提交。如果有失败的给与提示,删除或者重新上传
2.index不能作为唯一标识,没有唯一标识的要手动加上,确保删除的时候是删除的那一项,图片上传成功后也要找到上传前的唯一标识去进行数据处理

最后,遇到问题不要慌,找到问题的所在点,然后去解决,实战中学习,加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值