1.使用form表单实现文件上传
<form method="POST" action="接口地址" enctype="multipart/form-data">
<input name="file" type="file" />
<input type="submit" />
</form>
2.基于Element前端UI组件库进行文件上传/Upload 上传
文件上传:假如是第一次上传文件,组件上传按钮旁边一片空白,不展示相应的文件标识,而如果点击上传文件并上传成功,则通过组件自带的文件展示方式展示文件,如果编辑文件上传,则默认将相应的文件展示出来。
本次功能实现交互:该操作不是将文件一次性上传到服务器,而是分两次操作,第一次点击上传按钮将文件上传为临时文件并返回一个临时文件id,第二次提交表单保存时将临时文件id上传给后台,将临时文件转为正式文件保存起来。
<!-- html代码 -->
<el-form>
...
<el-form-item class="form-uploaditem" label="文件" prop="oldFileName" ref="uploadItem">
<el-upload ref="upload" class="form-upload" action="/api/base/file/addTemplUpload" :before-upload="handleUpload"
:on-success="handleFileSuccess" :on-error="handleFileError" :on-change="handleChange"
:on-remove="handleFileRemove" :show-file-list="true" :disabled="isProcess" :file-list="fileList">
<!-- 通过isProcess控制按钮的文字颜色、背景,通过uploadTxt控制按钮文本 -->
<el-button :class="{'form-upload-process': isProcess}" size="small" type="primary" v-text="uploadTxt"></el-button>
</el-upload>
<!-- 当编辑文件并且showFile为true时,显示默认文件文本块 -->
<p class="form-file" v-if="dialogTit === '编辑文件' && showFile"><span class="form-file-txt" v-text="file"
:title="file"></span><span class="form-file-tip">(默认文件,请点击左边按钮进行修改)</span></p>
</el-form-item>
...
</el-form>
// js代码
export default {
data () {
return {
form: {
oldFileName: '' // 绑定表单的选项值,用于做表单校验和动态绑定文件名
}
// 保存默认文件名,当刚进入编辑弹框时显示默认文件名
file: '',
// 是否展示默认文件块
showFile: false,
// 绑定upload组件中的文件列表,用于控制一个文件上传
fileList: [],
// 上传按钮文本
uploadTxt: '点击上传',
// 文件上传状态,false标识未上传,true标识正在上传
isProcess: false,
// 文件tempId
tempId: '',
// 正式文件id
activeId: '',
// 文件上传次数
uploadCount: 0
}
},
methods: {
//限制文件长传大小
limitFileSize(file, limitSize) => {
let arr = ['KB', 'MB', 'GB']
let limit = limitSize.toUpperCase()
let limitNum = 0
for (let i = 0; i < arr.length; i++) {
let leval = limit.indexOf(arr[i])
if (leval > -1) {
limitNum = parseInt(limit.substr(0, leval)) * Math.pow(1024, (i + 1))
break
}
}
if (file.size > limitNum) {
return false
}
return true
}
// 文件上传组件上传文件前的钩子
handleUpload (file) {
// limitFileSize方法判断文件是否超出某个大小,当超出则提示
if (!this.limitFileSize(file, '10MB')) {
this.$message.warning({
message: '请上传10M以内的文件',
type: 'warning'
})
this.fileList = []
return false
}
// 如果文件大小符合要求,则将按钮文本设为“上传中”,将上传状态设为上传中
this.uploadTxt = '上传中'
this.isProcess = true
// 如果默认文件文本块是显示的,则这时将文本块隐藏起来
if (this.showFile) {
this.showFile = false
}
},
// 文件上传成功时监听钩子
handleFileSuccess (res, file) {
this.tempId = res.data.id // 保存临时文件id
this.uploadCount++
// 上传成功之后将上传状态改成未上传中,按钮文本设置成“重新上传”
this.isProcess = false
this.uploadTxt = '重新上传'
// 将文件上传表单项的校验清空
this.$refs['uploadItem'].clearValidate()
// 用form里的oldFileName记录下当前上传成功的文件名
this.form.oldFileName = file.name
this.$message.success('文件上传成功')
},
// 文件上传失败时钩子
handleFileError(err, file, fileList) { // eslint-disable-line
// 上传失败时将上传状态改成未上传中
this.isProcess = false
// 如果已经上传成功过至少一次,文件上传失败会将文件标识给删除,故而需要将文件名置空
if (this.uploadCount !== 0) {
this.form.oldFileName = ''
// 如果还未上传成功过一次文件,且本次为编辑文件,则需要将默认文件文本显示出来
} else if (this.uploadCount === 0 && this.file !== '') {
this.showFile = true
}
// 文件上传按钮根据oldFileName调整文本
this.uploadTxt = this.form.oldFileName !== '' ? '重新上传' : '点击上传'
this.$message.error('文件上传失败!')
},
// 文件组件状态发生变化时
handleChange (file, fileList) {
// 控制文件只能上传一个
this.fileList = fileList.slice(-1)
},
// 文件被移除时
handleFileRemove(file, fileList) { // eslint-disable-line
if (this.uploadCount === 0) {
return
}
this.uploadTxt = '点击上传'
this.form.oldFileName = ''
}
}
}
第一次上次前按鈕文字为点击上传,上传时按钮样式改变文字为上传中,上传成功后文字为重新上传,右侧显示第一次上传的文件名。第二次上传时如果上传失败,按钮文字为点击上传,将第一次上传成功的文件名清空,效果图如下
图片上传:规定上传的文件只是图片,也就是上传配图,同样的,第一次上传时组件上传按钮旁边一片空白,如果点击上传文件并上传成功,则展示相应的图片,并将组件默认的文件展示效果隐藏,如果是编辑图片上传,则默认将相应的图片展示。交互与文件上传的是一样的。
<!-- html代码 -->
<el-form-item
label="深底logo"
prop="img"
ref="uploadItem"
>
<el-upload
ref="upload"
class="form-upload"
action="/api/base/file/addTemplUpload"
:before-upload="handleUpload"
:on-success="handleFileSuccess"
:on-error="handleFileError"
:show-file-list="true"
:limit="1"
:disabled="isProcess1"
>
<el-button
:class="{'form-upload-process': isProcess}"
size="small"
type="primary"
v-text="uploadTxt"
></el-button>
<img
slot="tip"
class="form-img"
v-if="uploadTxt === '重新上传'"
v-lazy="form.img"
alt=""
>
</el-upload>
</el-form-item>
// js代码
export default {
data () {
return {
form: {
img: '',
tempId: ''
},
uploadTxt: '点击上传',
isProcess: false
}
},
methods: {
// 监听图片上传开始
handleUpload (file) {
if (!limitFileSize(file, '2MB')) {
this.$message.warning({
message: '请上传2MB以内的文件',
type: 'warning'
})
return false
}
let img_mimes = [
'image/gif',
'image/jpeg',
'image/png',
'image/tiff',
'image/vnd.wap.wbmp',
'image/x-icon',
'image/x-jng',
'image/x-ms-bmp',
'image/svg+xml',
'image/webp'
]
//限制只能上传图片
if (img_mimes.indexOf(file.type) === -1) {
this.$message.warning({
message: '请上传一张图片',
type: 'warning'
})
return false
}
this.uploadTxt = '上传中'
this.isProcess = true
},
// 监听图片上传成功
handleFileSuccess(res, file) { // eslint-disable-line
this.isProcess = false
this.uploadTxt = '重新上传'
this.form.img = res.data.url
this.form.tempId = res.data.id
this.$message.success('文件上传成功')
// 将上传组件所对应的表单项的校验去除
this.$refs['uploadItem'].clearValidate()
// 将上传组件自带的图片标识消除,以自定义的图片区域展示图片
this.$refs['upload'].clearFiles()
},
// 监听图片上传失败
handleFileError(err, file, fileList) { // eslint-disable-line
this.isProcess = false
this.uploadTxt = this.form.img !== '' ? '重新上传' : '点击上传'
this.$message.error('文件上传失败!')
}
}
}
效果图如下:第一次上传按钮为点击上传,上传时按钮为上传中按钮样式发生改变,上传完成,将图片显示字右侧。当选择的文件不是图片提示请选择图片,不向下进行操作,按钮为重新上传
以上的文件上传和图片上传的基本思路相似