自己实现文件上传功能

栏目: JavaScript · 发布时间: 7年前

内容简介:本文采用的是vue框架,但是不管什么框架,原理是相通的,所以希望大家不要将自己的格局局限在 框架里。说句题外话,最近尤雨溪说要开发vue 3.0 了,而且听说变动挺大的。我倒是觉得其实没什么大不了的。我准备趁着这个机会学习一下React,然后找个小项目实践一下。毕竟学习vue 3.0 也是学,学React也是学,那我更想了解下更多的知识。好了,言归正传,使用第三方的组件库,总是觉得修改起来很麻烦,所以在最近的项目中才决定自己实现一套文件上传的功能。

本文采用的是vue框架,但是不管什么框架,原理是相通的,所以希望大家不要将自己的格局局限在 框架里。

说句题外话,最近尤雨溪说要开发vue 3.0 了,而且听说变动挺大的。我倒是觉得其实没什么大不了的。我准备趁着这个机会学习一下React,然后找个小项目实践一下。毕竟学习vue 3.0 也是学,学React也是学,那我更想了解下更多的知识。

文件上传功能开发

好了,言归正传,使用第三方的组件库,总是觉得修改起来很麻烦,所以在最近的项目中才决定自己实现一套文件上传的功能。

其实使用HTML的input标签是可以实现文件选择功能的,然后再将选择的文件通过http请求传送到后台就行了。具体代码如下:

<input id="upload" type="file">
复制代码

通过将input标签的type设为file就可以实现文件选取的功能了。然后通过选择器读取选取的文件信息即可。

let uploadFile = document.querySelector("#uploadMission")
let form = new FormData()
form.append('file', uploadFile.files[0])
form.append('yourData', "helloworld")
复制代码

yourData就是你希望传送给后台的除了file字段以外的字段,请求的参数格式为:

{
    file: 这里是一大段文件信息,
    yourData: helloworld
}
复制代码

所以可以根据实际情况进行传参。

自定义文件上传样式

可是有一个问题,就是:html的样式很丑,完全不符合UI设计,而且还不好改。所以我采取的方案是:自己定义一个样式,然后点击的时候实际调用原生的input标签。这样你想让样式展示成什么样都行,不过记得要将原生的input标签进行隐藏哦。具体代码如下:

<span class="yourStyle" @click="uploadFile">上传文件</span
<input id="upload" type="file" @change="doRealUpload" style="display: none;">
复制代码

当点击uploadFile时,主动调用input的click事件,触发文件选择功能,选取完文件之后,文件会被读取到input标签中。我们只需要按照上面 文件上传功能开发 的流程进行处理即可。

有一点需要注意的是:文件选择完之后会触发input标签的change事件,这时候才能读取到文件信息。所以记得将文件传送至后台的操作放在doRealUpload方法中。

解决重复上传同一文件无效问题

经过上面的步骤,其实已经可以实现自定义文件上传功能了。但是总有人喜欢将同一个文件经过修改后重复上传。但是因为input的change事件是通过文件路径来识别是否为同一文件的,如果文件名或路径不改,即使文件内容修改了,在重复上传时也无法触发change事件。

本来我想着将upload.files[0]的值置为null不就解决了么?但是这是只读属性了,根本改不了。然后我又想着,应该会有clear方法,将文件信息清空吧?可惜也没有。。。

场面一度很尴尬,于是我就想出了让input标签重新加载的方法,这样等于是将input标签进行了初始化,里面保存的文件信息当然也一并消除啦。

有的人可能会想要通过DOM操作重新生成一个新的同样的input标签。这样当然是可行的。但是这让我觉得采用的JQuery的老思想,并不合符Vue以数据为核心的原则。所以我利用了Vue中v-if与v-show的特性。

Vue中v-if的标签每次是重新加载的,而v-show则是在一开始就进行加载,随后直接读缓存。所以我将input标签加上v-if,然后每次调用uploadFile方法的时候将inputShow置为true,而在文件上传成功后的回调函数中将inputShow置为false。这样每次点击上传按钮的时候都会重新加载一次input标签,也就是对input进行初始化操作。

具体代码如下:

uploadFile() {
    const vm = this
    vm.inputShow = true
    setTimeout( () => {
        let uploadFile = document.querySelector("#upload")
        uploadFile.click()
    }, 100)
}
复制代码

这里之所以要加setTimeout方法,是因为不加的话可能会因为代码执行速度比DOM的渲染速度要快而导致,在执行选择操作的时候报错。因为执行click事件的时候input标签还没创建完成呢。

结束语

到这里我们的自定义文件上传功能就完成啦。如果你喜欢本篇文章记得点关注哦,你的支持是我继续分享的最大动力。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Code

Code

Charles Petzold / Microsoft Press / 2000-10-21 / USD 29.99

Paperback Edition What do flashlights, the British invasion, black cats, and seesaws have to do with computers? In CODE, they show us the ingenious ways we manipulate language and invent new means of ......一起来看看 《Code》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具