1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > Vue+Axios 文件上传 自定义进度条

Vue+Axios 文件上传 自定义进度条

时间:2023-04-16 05:25:04

相关推荐

Vue+Axios 文件上传 自定义进度条

前文:之前一直用Elemet-UI的upload组件,但是ui给出的样式Element-UI满足不了,所以决定自己写一个玩玩

总体分三步:

页面布局(自定义上传组件样式)Axios上传监听Process 联动页面实现进度条

成果

1、页面布局

<div class="display-upload-wrapper"><div class="innier-upload-wrapper" :style="innerUploadStyle">自定义的upload样式<div v-if="fileInfo">{{ fileInfo.name }}.{{ fileInfo.format }} 上传完成</div></div></div><input id="upload-file" ref="uploadInput" type="file" @change="getFile">

通过input file 上传文件,原生的upload input 太丑了,好多人是不是都忘接了什么样子了,我帮大家回忆一下

我们可以通过css隐藏这个文件,让后用js 给其他的dom绑定上这个input的点击事件实现

CSS

.display-upload-wrapper {border: 1px solid red;width: 384px;height: 54px;cursor: pointer;width: 244px;border-radius: 4px;background: #F4F8FF;.innier-upload-wrapper {height: 100%;background: linear-gradient(270deg, #C0D8FF 0%, #E7F2FF 100%);background-repeat: no-repeat;background-size: 10% 100%;transition: background-size .3s linear;}}#upload-file {display: none;}

js

document.querySelector('.display-upload-wrapper').onclick = function() {document.querySelector('#upload-file').click()}

这样点击就可以调起文件选择

2、Axios上传

获取到选中的文件

getFile() {const file = this.$refs.uploadInput.files[0]if (!file) return// 获取到的file用FormData处理成表单键值对const formData = new FormData()formData.append('file', file)//uplaodFileApi是文件上传的api 第一个入参为上传的文件,第二个入参为上传的进度的回调uplaodFileApi(formData, this.onProcess).then(res => {console.log('uplaodFileApi succ: ', res)const { success, msg, data } = resif (success) {this.fileInfo = data}})},

获取到的file用FormData处理成表单键值对

const formData = new FormData()

formData.append('file', file)Axios的入参为

{"method":"POST","url":"/jz/boss/public/upload/b","data":{},"params":{"appToken":"xxxxxxxxxxxxxxxxxxxxx ="},"withCredentials":true,"headers":{"Content-Type":"multipart/form-data;charset=UTF-8"},"responseType":""}

data的值就是传入的fromData,控制台直接打印不出的

要注意的是 headers的Content-Type 要设置成multipart/form-data;charset=UTF-8"

Content-Type":"multipart/form-data;charset=UTF-8"

做完这些操作我们就可以上传成功了

3、监听Process 联动页面实现进度条

Axios提供了onUploadProgress的回调

所有原生的processs的处理都可以,下面的图就是这个回调的progressEvent

用total 和loaded我们就可以算出进度条的百分比

onProcess(e) {const { loaded, total } = econst uploadPrecent = ((loaded / total) * 100) | 0this.uploadPrecent = uploadPrecent},

完整代码

<template><div>{{ uploadPrecent }}%<div class="display-upload-wrapper"><div class="innier-upload-wrapper" :style="innerUploadStyle">自定义的upload样式<div v-if="fileInfo">{{ fileInfo.name }}.{{ fileInfo.format }} 上传完成</div></div></div><input id="upload-file" ref="uploadInput" type="file" @click="clearPreUpload" @change="getFile"></div></template><script>import { uplaodFileApi } from '@/api/uploadApi'import { UploadStatus } from './format'export default {name: 'Myupload',data() {return {uplaodStatus: UploadStatus.wait,uploadPrecent: 0,timer: undefined,fileInfo: undefined}},computed: {innerUploadStyle() {return `background-size: ${this.uploadPrecent}% 100%;`}},mounted() {this.bindUplaodClickToDisplayUplaod()},methods: {bindUplaodClickToDisplayUplaod() {document.querySelector('.display-upload-wrapper').onclick = function() {document.querySelector('#upload-file').click()}},getFile() {const file = this.$refs.uploadInput.files[0]if (!file) returnconst formData = new FormData()formData.append('file', file)uplaodFileApi(formData, this.onProcess).then(res => {const { success, msg, data } = resif (success) {this.fileInfo = data}})},onProcess(e) {const { loaded, total } = econst uploadPrecent = ((loaded / total) * 100) | 0this.uploadPrecent = uploadPrecent},clearPreUpload() {}}}</script><style lang="scss" scoped>.display-upload-wrapper {border: 1px solid red;width: 384px;height: 54px;cursor: pointer;width: 244px;border-radius: 4px;background: #F4F8FF;.innier-upload-wrapper {height: 100%;background: linear-gradient(270deg, #C0D8FF 0%, #E7F2FF 100%);background-repeat: no-repeat;background-size: 10% 100%;transition: background-size .3s linear;}}#upload-file {display: none;}</style>

这个请求代码删减过 仅供参考可以理解为 伪代码

const HttpRequest = (type, option) => {const options = {expirys: true,...option}return new Promise((resolve, reject) => {const queryParams ={method: type,url: options.url,data: options.data,params: { appToken: requestToken() },withCredentials: true,headers: options.header ? options.header : DEFAULT_HEADER,responseType: options.responseType || ''}// 如果有onProcess就给axios绑定onUploadProgress回调if (options.onProcess) {queryParams.onUploadProgress = options.onProcess}if (options.timeout) {queryParams.timeout = options.timeout}axios(queryParams).then(res => {const { data = {}, headers = {} } = res || {}const result = Object.assign(data, headers)resolve(result)},err => {reject(err)}).catch(error => {reject(error)}).finally(() => {})})}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。