vue + element 实现文件上传
当时写文件上传是一件让人难受的事情,测试了很久,终于完成。写完之后超超超超超超级开心~效果如下图:功能描述:点击添加,可以增加多条,如下图:2. 点击删除,顾名思义,删掉这一行。3. 点击照片后面的 x 号,进行图片删除或更改如图:4. 点击确定按钮,整合内容提交给接口难点攻克:选择一个文件上传,添加第二条时,文件展示有误如果我一次增加了多条上传框,但从非第一个的上...
当时写文件上传是一件让人难受的事情,测试了很久,终于完成。
写完之后超超超超超超级开心~
效果如下图:
功能描述:
- 点击添加,可以增加多条,如下图:
2. 点击删除,顾名思义,删掉这一行。
3. 点击照片后面的 x 号,进行图片删除或更改
如图:
4. 点击确定按钮,整合内容提交给接口
难点攻克:- 选择一个文件上传,添加第二条时,文件展示有误
- 如果我一次增加了多条上传框,但从非第一个的上传按钮上传时,添加到了第一个点击上传的按钮下
- 图片的自删和更换
- 最后的上传格式
嗯,从以上几点来一步步来处理问题
第一步,写出基本上传html:
// fileUploadLength 是要添加几条tr的总个数
<tr v-for="(item,index) in fileUploadLength" :key="index" style="width: 100%;height: 50px;">
<td>
<input class="desc"> // 文件描述
</td>
<td>
<input class="ver"> // 文件版本
</td>
<td style="width: 100px">
//上传 - 官网中就有
<el-upload
:on-remove="handleRemove" // 文件列表移除文件时的钩子
:before-upload="beforeUpload" // 上传文件之前的钩子,参数为上传的文件
:before-remove="beforeRemove" // 删除文件之前的钩子,参数为上传的文件和文件列表
:limit="1" // 限制,每个上传按钮只能上传一个文件
:file-list="fileList[index]" // 文件组
:multiple="false"
:on-exceed="handleExceed" // 文件超出个数限制时的钩子
class="upload-demo"
action="">
<el-button size="mini" type="primary" @click="clickUpload(index)">{{ $t('file.click_upload') }}</el-button>
</el-upload>
</td>
<td>
// 删除按钮
<el-button type="text" @click="deleteTr(index)">{{ $t('table.delete') }}</el-button>
</td>
</tr>
第二步,充实对应的方法:
1. 只要点击上传就会执行该方法:
// 文件上传之时(文件不会上传成功,在触发下一步操作前截取文件信息)
beforeUpload(file) {
if (file) {
// 添加-跳跃增 => 只能添加到第一位,后面的全删掉
if (this.index === 0 && this.iNotUpload !== 0 && !this.addUpload) {
this.fileUploadLength.splice(this.iNotUpload, this.fileUploadLength.length)
}
this.fileList[this.index++].push(file)
}
return false
},
现在来说一下,为什么官网直接用的是 fileList,而我的代码用的是 fileList[0]这样的呢?
由于在这个添加会有增加多条tr,而每个tr都有一个上传按钮,如果直接用fileList,当我上传第一个文件之后,
再添加第二条,就会出现第二个文件名也出现在了第一个上传按钮下方的情况。
所以,为了文件和按钮的位置一一对应,使用下标控制。
2. 上传后 return false 相当于上传并没成功,就会自动执行删除操作:
// 文件列表移除文件时的钩子(就是点击文件后的 x 进行删除或更改的操作)
handleRemove(file) {
// 防止 上传没成功就直接删除了文件。
if (file && file.status === 'success') {
for (let i = 0; i < this.fileList.length; i++) {
// 若是点击要删除的文件名与文件组中的某个文件名相同,则取其下标
if (this.fileList[i].length && file.name === this.fileList[i][0].name) {
this.fileList.splice(i, 1)
this.index = i
this.fileList.splice(i, 0, []) // 删除该下标对应文件后,给该下标插入空数组占位,保证fileList长度
this.addUpload = true
}
}
}
},
3. 删除之前的询问
// 删除文件之前的钩子-弹出框询问
beforeRemove(file, fileList) {
// 处理 before-upload验证不通过后触发了on-remove的解决办法
if (file && file.status === 'success') {
return this.$confirm('你确定删除这个文件?')
}
},
4. 限制每个上传按钮对应文件的个数
// 一个上传按钮只能添加一个文件,限制,不能超过一
handleExceed(files, fileList) {
this.$message.warning(this.$t('file.select_aPage'))
},
和组件中的 :limit 共同使用
5. 上传:
// 点击上传按钮,按照下标上传,处理同时有多个上传按钮 但不按顺序上传的问题
clickUpload(i) {
// 新增-上传
if (i !== 0 && !this.addUpload) {
this.iNotUpload = i
}
},
6. tr 的增加:
// tr的添加按钮
addTr() {
// 保证添加首条后再点击添加按钮首条添加文件不会消失
if (this.fileList.length) {
this.fileList = this.fileList
} else {
this.fileList = []
}
this.fileUploadLength.push(0)
for (let i = 0; i < this.fileUploadLength.length; i++) {
this.fileList.push([])
}
},
7. tr 的删除:
// tr的删除按钮
deleteTr(index) {
this.fileList.splice(index, 1)
this.fileUploadLength.splice(index, 1)
this.index--
},
前三个难点在上述代码中已经解决:
难点一 => 下标控制
难点二 => 上传前触发的钩子方法中,跳跃增的处理
难点三 => 第二段代码,用splice(下标,个数,插入[ ])
现在来处理最后一个难点: 走接口上传!
当时在网上找资料的时候,看到组件中的action里必须要写内容,官网中也是:
所以我在这里是懵的,最后发现写不写都没啥影响,反正用不到里面的地址,最后都是要走接口的。
方法详情参照链接:https://www.jianshu.com/p/e984c3619019
最后整理文件:
var formdata = new FormData() // 创建一个对象实例
// 我们后台不识别直接传一个数组过去,分割成对象
for (let i = 0; i < this.fileList.length; i++) {
if (this.fileList[i].length) {
formdata.append('files', this.fileList[i][0])
}
}
// 若是后台能接收到完整的数组(前提是把fileList中的数组拆成对象):
formdata.append('files', this.fileList)
// 键值对类型(this.valObj对象是存放一些别的参数的)
formdata.append('msgupgradeFileGroup', JSON.stringify(this.valObj))
这些功能是需要前后端联调的,最终完成真的特棒。
项目中有添加也有编辑,这里只是整理了添加,编辑的话也都大同小异。希望以后会更进一步!
更多推荐
所有评论(0)