1. 简介
文件上传和下载是Web开发中常见的功能要求之一。在Vue框架中,使用Element-plus插件可以方便地实现文件上传和下载的功能。本文将介绍如何使用Vue和Element-plus实现文件上传和下载,并在上传和下载过程中展示进度。
2. 文件上传
2.1 安装Element-plus
首先,我们需要安装Element-plus插件。在终端中运行以下代码:
npm i element-plus -S
安装完成后,在main.js中引入该插件:
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/lib/theme-chalk/index.css'
import App from './App.vue'
import router from './router'
const app = createApp(App)
app.use(ElementPlus)
app.use(router)
app.mount('#app')
2.2 模板代码
接下来,我们需要编写文件上传的模板代码。
<template>
<el-upload
class="upload-demo"
:action="uploadUrl"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-upload="beforeUpload"
:on-success="handleSuccess"
:on-error="handleError"
:file-list="fileList"
multiple>
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
<template slot="tip">只能上传jpg/png文件,且不超过500kb</template>
</el-upload>
</template>
<script>
import { ref } from 'vue'
export default {
name: 'uploadDemo',
setup() {
const fileList = ref([])
const uploadUrl = 'https://jsonplaceholder.typicode.com/posts/'
const beforeUpload = (file) => {
if (file.type !== 'image/png' && file.type !== 'image/jpeg') {
alert('只能上传jpg/png文件哦!')
return false
}
if (file.size > 500 * 1024) {
alert('文件大小不能超过 500KB!')
return false
}
return true
}
const handleSuccess = (response, file, fileList) => {
console.log(response, file, fileList)
alert('上传成功')
}
const handleError = (err, file, fileList) => {
console.log(err, file, fileList)
alert('上传失败')
}
const handlePreview = (file) => {
console.log(file)
}
const handleRemove = (file, fileList) => {
console.log(file, fileList)
}
return {
fileList,
uploadUrl,
beforeUpload,
handleSuccess,
handleError,
handlePreview,
handleRemove
}
}
}
</script>
这里使用了Vue3中的Composition API来编写组件。在setup函数中定义了一些变量和函数,用于控制文件上传的行为。
2.3 代码解析
接下来,我们分别对上传组件中的代码进行解析和说明。
2.3.1 el-upload组件
上传组件是通过Element-plus中的el-upload组件实现的:
<el-upload
class="upload-demo"
:action="uploadUrl"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-upload="beforeUpload"
:on-success="handleSuccess"
:on-error="handleError"
:file-list="fileList"
multiple>
<el-button slot="trigger" size="small" type="primary">选取文件</el-button>
<template slot="tip">只能上传jpg/png文件,且不超过500kb</template>
</el-upload>
这里我们使用了el-upload组件来实现文件上传功能。这个组件包含了一些属性和事件,用于控制上传行为。下面我们简单说明一下这些属性和事件的含义:
class: 为组件添加CSS类名
action: 上传的地址,可以是一个API接口
before-upload: 文件上传前的检查函数,可以在此处检查文件类型和大小等信息
on-success: Upload组件上传成功后调用的方法
on-error: Upload组件上传失败后调用的方法
fileList: 已上传的文件列表
在组件模板中,我们还定义了一个el-button
组件,用于触发上传操作。
2.3.2 属性和事件
接下来我们来详细解析一下组件中定义的属性和事件:
:before-upload
:before-upload
属性是一个上传前的检查函数,用于检查文件的类型和大小等信息。如果检查失败,可以返回一个 false
来中止上传。
const beforeUpload = (file) => {
if (file.type !== 'image/png' && file.type !== 'image/jpeg') {
alert('只能上传jpg/png文件哦!')
return false
}
if (file.size > 500 * 1024) {
alert('文件大小不能超过 500KB!')
return false
}
return true
}
当文件类型不是png或者jpeg时,我们会弹出提示框,中止上传。同样,当文件大小超过500KB时,也会中止上传。
:on-success
:on-success
事件会在文件上传成功后触发,同时返回上传成功的信息。在这里,我们只是给用户一个提示框,告诉他文件上传成功了:
const handleSuccess = (response, file, fileList) => {
console.log(response, file, fileList)
alert('上传成功')
}
:on-error
:on-error
事件会在文件上传失败后触发,同时返回上传失败的信息。在这里,我们只是给用户一个提示框,告诉他文件上传失败了:
const handleError = (err, file, fileList) => {
console.log(err, file, fileList)
alert('上传失败')
}
:file-list
:file-list
属性是已上传的文件列表。在上面的组件中,我们使用 ref
来定义了一个 fileList
变量。
import { ref } from 'vue'
export default {
name: 'uploadDemo',
setup() {
const fileList = ref([])
// ...
return { fileList /* ... */ }
}
}
我们可以通过 ref
来定义一个变量,并在其他地方引用它。这里,我们将 fileList
变量作为一个属性,传递给el-upload组件,就可以把已上传的文件列表显示在界面上。
3. 文件下载
3.1 下载文件
接下来,我们来实现文件下载的功能。在Vue中,可以通过定义一个a标签来触发文件下载。我们可以通过在a标签的href属性中指定文件下载的地址,然后调用js代码的click方法来下载文件。
<template>
<div>
<a :href="downloadUrl" @click="downloadFile">下载文件</a>
</div>
</template>
<script>
export default {
name: 'downloadDemo',
data() {
return {
downloadUrl: 'https://jsonplaceholder.typicode.com/posts/1'
}
},
methods: {
downloadFile() {
window.open(this.downloadUrl, '_blank')
}
}
}
</script>
注意,这里的下载文件并不会显示进度条,这只是一个简单的下载示例。
3.2 显示进度条
为了在文件上传和下载的过程中展示进度条,我们需要使用axios库。axios是一个流行的HTTP库,可以在浏览器中发出AJAX请求,并支持PromiseAPI。
3.3 安装axios
首先,我们需要安装axios库。在终端中运行以下代码:
npm i axios -S
安装完成后,在main.js中引入该库,并将其绑定到Vue的原型链中:
import { createApp } from 'vue'
import ElementPlus from 'element-plus'
import 'element-plus/lib/theme-chalk/index.css'
import App from './App.vue'
import router from './router'
import axios from 'axios'
const app = createApp(App)
app.use(ElementPlus)
app.use(router)
app.config.globalProperties.$axios = axios
app.mount('#app')
现在我们已经可以在Vue组件中使用axios了。
3.4 文件下载进度
下面我们要实现的是文件下载时的进度条显示。
<template>
<div>
<el-button type="primary" @click="downloadFile">下载文件</el-button>
<el-progress :percentage="progressPercentage" :status="progressStatus">{{progressText}}</el-progress>
</div>
</template>
<script>
export default {
name: 'downloadProgressDemo',
data() {
return {
downloadUrl: 'https://jsonplaceholder.typicode.com/posts/1',
progressStatus: 'info',
progressPercentage: 0,
progressText: ''
}
},
methods: {
downloadFile() {
const url = this.downloadUrl
const downloadElement = document.createElement('a')
document.body.appendChild(downloadElement)
downloadElement.setAttribute('href', url)
downloadElement.setAttribute('download', '')
downloadElement.setAttribute('target', '_blank')
downloadElement.click()
const config = {
onDownloadProgress: (progressEvent) => {
this.progressStatus = 'success'
this.progressPercentage = Math.round((progressEvent.loaded / progressEvent.total) * 100)
this.progressText = `${this.progressPercentage}% 下载完成`
}
}
this.$axios({
method: 'get',
url: url,
responseType: 'arraybuffer',
...config
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
}
}
}
</script>
这里定义了一个名为downloadProgressDemo的Vue组件,用于展示文件下载进度。在这个组件中,我们定义了一些变量和方法,用于控制进度条的显示。
在模板中,我们定义了一个按钮,用于触发文件下载功能,并在下面添加了一个进度条,用于展示下载的进度。
3.5 代码解析
3.5.1 点击下载按钮
下载文件的按钮对应以下代码:
<el-button type="primary" @click="downloadFile">下载文件</el-button>
点击下载按钮后,会调用 downloadFile 方法。
3.5.2 下载文件方法
在 downloadFile 方法中,我们通过创建一个a标签,将下载链接放在href属性中,然后通过调用click方法来下载文件。同时,在 axios 中设置了 onDownloadProgress 回调方法,用于每次下载时调用以更新进度条。
methods: {
downloadFile() {
const url = this.downloadUrl
const downloadElement = document.createElement('a')
document.body.appendChild(downloadElement)
downloadElement.setAttribute('href', url)
downloadElement.setAttribute('download', '')
downloadElement.setAttribute('target', '_blank')
downloadElement.click()
const config = {
onDownloadProgress: (progressEvent) => {
this.progressStatus = 'success'
this.progressPercentage = Math.round((progressEvent.loaded / progressEvent.total) * 100)
this.progressText = `${this.progressPercentage}% 下载完成`
}
}
this.$axios({
method: 'get',
url: url,
responseType: 'arraybuffer',
...config
})
.then(response => {
console.log(response)
})
.catch(error => {
console.log(error)
})
}
}
其中 config
是一个axios请求的配置,它定义了一个 onDownloadProgress
方法,在每次下载时被调用以更新进度条。在这个方法中,我们通过计算已下载的数据量与总数据量的比例来计算进度百分比。然后将进度百分比更新到 progressPercentage 变量中,并将进度文本更新到 progressText 变量中。最后,我们将 progressStatus 设置为 'success',将进度条设置为绿色。
3.5.3 显示进度条
在模板代码中,我们使用 Element-plus 中的 el-progress
组件来展示进度条:
<el-progress :percentage="progressPercentage" :status="progressStatus">{{progressText}}</el-progress>
这里我们绑定了 :percentage
属性和 :status
属性,用于显示进度百分比和状态。同时,将进度文本作为插槽内容显示。
4. 总结
在本文中,我们介绍了如何使用Vue和Element-plus来实现文件上传和下载的功能,并在文件上传和下载的过程中展示进度条。借助于Element-plus和axios,我们可以很方便地实现这些功能,并且可以自定义进度条的样式和文本。希望本文对你有所帮助。