Vue?使用?ElementUi?el-upload?手動上傳文件限制上傳文件類型大小同名等進行限制
個人在做文件上傳功能的時候,踩過不少的坑,特在此記錄下,方便后續(xù)的查閱,也幫助有需要的個人在開發(fā)中,需要做文件的上傳,自己踩過不少的坑,于是決定在此記錄以下,方便自己后續(xù)查看,也方便有需要的朋友查閱。
實現(xiàn)的功能有:文件上傳類型限制、文件大小限制、文件總大小限制、文件同名限制、文件下載、文件刪除 和 文件預覽圖。
效果圖如下:
1. 文件類型限制

2. 文件大小限制

3. 文件同名限制

4. 文件總大小限制

5. 文件下載和刪除

6. 文件預覽圖就是上述的框體圖片,這個是自己引入的圖片,自己會放在附件處。有需要的可到 阿里巴巴icon圖庫官網(wǎng) 進行下載自己喜歡的圖片。
7. 點擊保存上傳文件等信息

下面來說下大致的實現(xiàn)過程,讓大家更明確一些。
前提:要手動上傳文件,需要將 :auto-upload="false" 加上,指的是不要自動上傳。自己書寫下 :http-request="handleUplodFile" 方法,覆蓋 action 即可。
自己定義了兩個變量:
fileList:[] : 是用于展示選擇的文件列表的,如上面的一個個的框體。
realUploadFile:[] :這個是真實的要上傳給后端的文件,該數(shù)組的類型是 二進制的Object 類型
下面直接說下關(guān)鍵的代碼
1. 文件上傳的時候,觸發(fā) on-change 事件,在這可做一些判斷。文件類型限制、文件大小限制、文件同名限制和文件總大小限制等等。
// 文件勾選觸發(fā)
changUpload(file) {
const { uid, name, size } = file
// 文件類型限制
const fileTypeFlag = /^.png|.jpg|.jpeg|.gif|.txt|.doc|.docx|.xls|.xlsx|.pdf|.zip|.7z|.rar$/.test(
name.substring(name.lastIndexOf('.')).toLowerCase()
)
if (!fileTypeFlag) {
this.$message.warning(
'文件類型只能是.png|.jpg|.jpeg|.gif|.doc|.docx|.xls|.xlsx|.pdf|.zip|.7z|.rar|.txt'
)
const selectFileList = this.modelForm.fileList.filter(item => {
return item.uid != uid
})
this.modelForm.fileList = selectFileList
return
}
// 文件大小進行校驗
if (size > 1024 * 1024 * 100) {
this.$message.warning('文件大小不能超過100Mb')
const selectFileList = this.modelForm.fileList.filter(item => {
return item.uid != uid
})
this.modelForm.fileList = selectFileList
return
}
// 文件總大小限制
const totalSize = this.modelForm.fileList.reduce(
(total, item) => total + item.size,
0
)
if (totalSize + size > 1024 * 1024 * 100) {
this.$message.warning('總文件大小不能超過100Mb')
const selectFileList = this.modelForm.fileList.filter(item => {
return item.uid != uid
})
this.modelForm.fileList = selectFileList
return
}
// 文件重名限制
const findCommonNameIndex = this.modelForm.fileList.findIndex(
item => item.name == name
)
if (findCommonNameIndex !== -1) {
this.$message.warning('不能上傳同名的文件')
const selectFileList = this.modelForm.fileList.filter(item => {
return item.uid != uid
})
this.modelForm.fileList = selectFileList
return
}
// 將上傳的文件信息存入列表
this.modelForm.fileList.push(file)
this.realUploadFile = []
},2. 文件的刪除和下載。刪除其實就是將已經(jīng)勾選的文件移除列表,下載就是創(chuàng)建 a 標簽,通過href 的方式下載。注意:在這不推薦使用 window.open, 因為下載下來的 的文件名是 哈希名,不符合要求。
// 移除不需要的文件
handleRemove(file) {
const { uid } = file
const selectFileList = this.modelForm.fileList.filter(item => {
return item.uid != uid
})
this.modelForm.fileList = selectFileList
},
// 下載文件
handleDownload(file) {
const { url, name } = file
let downloadLink = document.createElement('a')
downloadLink.href = url
downloadLink.download = name
document.body.appendChild(downloadLink)
downloadLink.click()
document.body.removeChild(downloadLink)
},3. 實際要上傳的文件。:http-request="handleUplodFile" 該事件就是自己實際要上傳的文件,觸發(fā)該方法是需要通過 this.$refs['uploadBlock'].submit() 來進行,然后就會將需要上傳的文件壓入數(shù)組中。
// 要上傳文件壓入數(shù)組
handleUplodFile(file) {
this.realUploadFile.push(file.file)
},
// 點擊保存
handleHttpUpload() {
this.$refs['uploadBlock'].submit()
......
}4. 點擊保存,上傳文件等相關(guān)信息。這里使用到的是 FormData() 對象,通過 append 追加的方式,將文件和其他信息放入該 FromData() 對象中。
// 點擊保存
handleHttpUpload() {
this.$refs['uploadBlock'].submit()
let formData = new FormData() //formdata格式
formData.append('info', JSON.stringify(this.modelForm))
this.realUploadFile.forEach(file => {
formData.append('file', file, file.name)
})
fileUpload(formData).then(resonse => {
console.log(resonse)
})
// 一定要先清空真實文件數(shù)組,免得點擊幾次,真實文件一直壓入該數(shù)組
this.$nextTick(() => {
this.realUploadFile = []
})
},5. 自己寫的后端 api 接口,以及如何使用她
/***** api 接口******/
export function fileUpload(data) {
return request({
url: '/file/upload',
method: 'post',
data
})
}
/*****調(diào)用api*****/
import { fileUpload } from '@/api/user'
......
fileUpload(formData).then(resonse => {
console.log(resonse)
})
/******** 提示:若是需要查看到文件上傳的進度,可以使用如下配置 ******************/
/***** api 接口******/
export function fileUpload(data, config) {
return request({
url: '/file/upload',
method: 'post',
data,
...config
})
}
/*****調(diào)用api*****/
import { fileUpload } from '@/api/user'
......
const config = {
timeout: 120000,
onUploadProgress: function(process) {
const num = process.loaded / process.total * 100 | 0
// 將數(shù)據(jù)賦值給進度條
this.processNum = num
}
}
fileUpload(formData, config).then(resonse => {
console.log(resonse)
})6. 完整的demo 代碼如下
<template>
<div>
<el-form ref="searchform" :model="modelForm" label-width="150px">
<el-form-item label="select多選demo:" prop="selectValue">
<el-select
v-model="modelForm.selectValue"
@change="changeSelect"
multiple
clearable
placeholder="請選擇"
>
<el-option key="selectAll" label="全部" value="selectAll"></el-option>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
>
</el-option>
</el-select>
</el-form-item>
<el-form-item label="附件" prop="fileList">
<el-upload
ref="uploadBlock"
action="#"
list-type="picture-card"
:file-list="modelForm.fileList"
accept=".png,.jpg,.jpeg,.gif,.txt,.doc,.docx,.xls,.xlsx,.pdf,.zip,.7z,.rar"
:auto-upload="false"
:on-change="changUpload"
:http-request="handleUplodFile"
>
<i slot="default" class="el-icon-plus"></i>
<div slot="file" slot-scope="{ file }">
<img
class="el-upload-list__item-thumbnail"
:src="getPreviwImg(file.name)"
alt=""
/>
<el-tooltip :content="file.name" placement="bottom" effect="light">
<span class="el-upload-list__item-actions">
<span
class="el-upload-list__item-delete"
@click="handleDownload(file)"
>
<i class="el-icon-download"></i>
</span>
<span
class="el-upload-list__item-delete"
@click="handleRemove(file)"
>
<i class="el-icon-delete"></i>
</span>
</span>
</el-tooltip>
</div>
</el-upload>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleHttpUpload">保存</el-button>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { fileUpload } from '@/api/user'
export default {
data() {
return {
options: [
{
value: '選項1',
label: '黃金糕'
},
{
value: '選項2',
label: '雙皮奶'
},
{
value: '選項3',
label: '蚵仔煎'
},
{
value: '選項4',
label: '龍須面'
},
{
value: '選項5',
label: '北京烤鴨'
}
],
modelForm: {
selectValue: [],
fileList: []
},
realUploadFile: [], // 真實上傳的文件
selectAll: false // 用于標識是否全選--默認不全選
}
},
created() {},
methods: {
changeSelect(value) {
// selectAll 為true 的時候,就走全選分支,全選后出現(xiàn)的情況就是取消權(quán)限
if (this.selectAll) {
this.selectAll = false
if (value.indexOf('selectAll') > -1) {
this.modelForm.selectValue = value.filter(p => p != 'selectAll')
} else {
this.modelForm.selectValue = []
}
} else {
// 是否點擊了‘全選'選項
if (value.indexOf('selectAll') > -1) {
// 有‘全選'選項,則將‘全部'和其他值放置一塊
const optionsValue = []
this.options.forEach(item => {
optionsValue.push(item.value)
})
this.modelForm.selectValue = ['selectAll', ...optionsValue]
this.selectAll = true
} else {
// 若是勾選選擇的長度和提供的選項長度是一樣的,則是 ‘全選'
if (value.length === this.options.length) {
const optionsValue = []
this.options.forEach(item => {
optionsValue.push(item.value)
})
this.modelForm.selectValue = ['selectAll', ...optionsValue]
this.selectAll = true
} else {
// 都是單選
this.modelForm.selectValue = value
}
}
}
// 真實的勾選值
const realSelect = this.modelForm.selectValue.filter(
item => item != 'selectAll'
)
console.log('realSelect', realSelect)
},
// 移除不需要的文件
handleRemove(file) {
const { uid } = file
const selectFileList = this.modelForm.fileList.filter(item => {
return item.uid != uid
})
this.modelForm.fileList = selectFileList
},
// 下載文件
handleDownload(file) {
const { url, name } = file
let downloadLink = document.createElement('a')
downloadLink.href = url
downloadLink.download = name
document.body.appendChild(downloadLink)
downloadLink.click()
document.body.removeChild(downloadLink)
},
// 文件勾選觸發(fā)
changUpload(file) {
const { uid, name, size } = file
// 文件類型限制
const fileTypeFlag = /^.png|.jpg|.jpeg|.gif|.txt|.doc|.docx|.xls|.xlsx|.pdf|.zip|.7z|.rar$/.test(
name.substring(name.lastIndexOf('.')).toLowerCase()
)
if (!fileTypeFlag) {
this.$message.warning(
'文件類型只能是.png|.jpg|.jpeg|.gif|.doc|.docx|.xls|.xlsx|.pdf|.zip|.7z|.rar|.txt'
)
const selectFileList = this.modelForm.fileList.filter(item => {
return item.uid != uid
})
this.modelForm.fileList = selectFileList
return
}
// 文件大小進行校驗
if (size > 1024 * 1024 * 100) {
this.$message.warning('文件大小不能超過100Mb')
const selectFileList = this.modelForm.fileList.filter(item => {
return item.uid != uid
})
this.modelForm.fileList = selectFileList
return
}
// 文件總大小限制
const totalSize = this.modelForm.fileList.reduce(
(total, item) => total + item.size,
0
)
if (totalSize + size > 1024 * 1024 * 100) {
this.$message.warning('總文件大小不能超過100Mb')
const selectFileList = this.modelForm.fileList.filter(item => {
return item.uid != uid
})
this.modelForm.fileList = selectFileList
return
}
// 文件重名限制
const findCommonNameIndex = this.modelForm.fileList.findIndex(
item => item.name == name
)
if (findCommonNameIndex !== -1) {
this.$message.warning('不能上傳同名的文件')
const selectFileList = this.modelForm.fileList.filter(item => {
return item.uid != uid
})
this.modelForm.fileList = selectFileList
return
}
// 將上傳的文件信息存入列表
this.modelForm.fileList.push(file)
this.realUploadFile = []
},
// 要上傳文件壓入數(shù)組
handleUplodFile(file) {
this.realUploadFile.push(file.file)
},
// 點擊保存
handleHttpUpload() {
this.$refs['uploadBlock'].submit()
let formData = new FormData() //formdata格式
formData.append('info', JSON.stringify(this.modelForm))
this.realUploadFile.forEach(file => {
formData.append('file', file, file.name)
})
fileUpload(formData).then(resonse => {
console.log(resonse)
})
this.$nextTick(() => {
this.realUploadFile = []
})
},
getImgUrl(image) {
return require(`@/assets/images/file/${image}`)
},
getPreviwImg(filename) {
filename = filename
.substring(filename.lastIndexOf('.'))
.toLowerCase()
.split('.')[1]
const imageObject = {
png: 'icon-png.png',
jpg: 'icon-jpg.png',
jpeg: 'icon-jpeg.png',
gif: 'icon-gif.png',
doc: 'icon-doc.png',
docx: 'icon-doc.png',
xls: 'icon-xls.png',
xlsx: 'icon-xls.png',
pdf: 'icon-pdf.png',
zip: 'icon-zip.png',
'7z': 'icon-zip.png',
rar: 'icon-zip.png',
txt: 'icon-txt.png'
}
return this.getImgUrl(imageObject[filename])
}
}
}
</script>
<style lang="scss" scoped></style>上述用到圖片的附件:










上一篇:第十五篇 VUE中使用 ElementUi 的 el-select 實現(xiàn)全選功能
到此這篇關(guān)于Vue 使用 ElementUi el-upload 手動上傳文件限制上傳文件類型大小同名等進行限制的文章就介紹到這了,更多相關(guān)Vue ElementUi el-upload上傳文件限制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Vue中通過Vue.extend動態(tài)創(chuàng)建實例的方法
這篇文章主要介紹了Vue中通過Vue.extend動態(tài)創(chuàng)建實例的方法,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2019-08-08
使用WebStorm用Debug模式調(diào)試Vue等前端項目的步驟
WebStorm提供了更簡單的前端調(diào)試方法,記錄一下WebStorm調(diào)試步驟啟動前端項目,這篇文章主要介紹了使用WebStorm用Debug模式調(diào)試Vue等前端項目的步驟,文中通過圖文介紹的非常詳細,需要的朋友可以參考下2024-11-11
Element-ui Drawer抽屜按需引入基礎(chǔ)使用
這篇文章主要為大家介紹了Element-ui Drawer抽屜按需引入基礎(chǔ)使用,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07
關(guān)于element-ui日期時間選擇器選不中12小時以后的時間詳解
在之前做個一個組件頁面中,引用了element-ui組件的日期選擇器,遇到的一個小問題,下面這篇文章主要給大家介紹了關(guān)于element-ui日期時間選擇器選不中12小時以后時間的相關(guān)資料,需要的朋友可以參考下2022-08-08

