美文网首页饥人谷技术博客
轮子之vue-uploader 图片上传

轮子之vue-uploader 图片上传

作者: fanlelee | 来源:发表于2020-06-15 00:08 被阅读0次

图片上传思路

  1. 选择图片:
    <input type="file" name="file" >
  2. 监听input变化,(选好图片后点击确定按钮就会触发):
    input.addEventListener('change',...)
  3. 通过FormData获取文件数据:
var formData = new FormData()
var inputFile = document.querySelector("input[name='file']")
formData.append('file', inputFile.files[0])
  1. 上传图片,获取服务器返回的图片地址,放进<img src=''>
var xhr = new XMLHttpRequest()
xhr.open('POST', url)
xhr.onload = () => {
    img.src = url2 + xhr.response
}
xhr.send(formData)

(这一步相当于预览)

  1. 点击页面按钮(确定、上传、提交...),向后台指定接口提交图片路径。

轮子vue-uploader:

效果图

填坑

  1. 实现点击上传按钮弹出文件选择框,但页面不能出现input输入框。可以给一个看不见的div,当点击上传按钮,通过DOM来给这个div一个input,绑定input的change事件,并执行input.click()
<button @click="onClickUpload">上传</button>
<div ref="input" style="width:0;height: 0;overflow: hidden;"></div>
onClickUpload() {
    let input = document.createElement('input')
    this.$refs.input.appendChild(input)
    input.type = 'file'
    input.multiple = true
    input.accept = 'image/*'
    input.addEventListener('change', () => {
        let files = input.files
        input.remove()
        this.uploadFile(files)
    })
    input.click()
}
  1. $emit 异步
    Uploader 组件中有一个propdata:fileList,用来监听和更新图片列表,当选择多张图片上传时,就要多次 emit('update:fileList', newFileList) ,始终只收到最后一张图片的更新消息。
    I:先举一个简单的例子问题重现:

    this.$emit('x',[...this.msgArray,1]) 
    this.$emit('x',[...this.msgArray,2])
    this.$emit('x',[...this.msgArray,3]) 
    

    II:结果,以上子组件的三次通知虽然是同步的,但始终只更新了最后一次的通知信息,即:this.msgArray只会多一个3 。
    III:原因,父子组件通信时,$emit是异步的,当所有代码执行完后,在render渲染任务队列里面,每一个任务再去读取msgArray的时候,读取的都是当前最新的this.msgArray,即[...this.msgArray,3]。
    IIII:那么回到Uploader 组件,选择多张图片多次执行emit('update:fileList', newFileList) 也只会更新最后一次通知。
    解决方案:

    方案1. 在父组件加一个新的监听,专门用来计算出msgArray。
    方案2. 子组件算出总的msgArray,一次性$emit通知给父组件,切勿一个一个去通知。

  2. 当遇到上传的图片名称相同时去重:

    avoidSameName(name) {
        while (this.fileList.filter((f) => f.name === name).length > 0) {
            let dotIndex = name.lastIndexOf('.')
            let nameWithoutExtension = name.substring(0, dotIndex)
            let nameExtension = name.substring(dotIndex)
            name = nameWithoutExtension + '(1)' + nameExtension
        }
        return name
    },
    

源码

Uploader源码
服务器源码

测试环境相关接口

提供一个用nodejs写的简易server,挂载在HEROKU运行,方便测试图片的上传、预览等。

  1. 图片上传请求地址:
    filename:'file'
    上传地址:https://node-server-uploadtest.herokuapp.com/upload

  2. 预览图片获取地址:
    'https://node-server-uploadtest.herokuapp.com/preview'+图片上传返回的id

相关文章

网友评论

    本文标题:轮子之vue-uploader 图片上传

    本文链接:https://www.haomeiwen.com/subject/npjztktx.html