工作需要, 要实现图片文档的上传查看下载等功能, 于是就基于 ele 的 upload 组件做了封装, 途中爬过几次坑, 给大家做一次分享, 共勉之!
1, 打开弹窗页面时, 获取上传列表
要在页面打开时请求列表接口, 获取数据 (若是页面建议放在 mounted 里面, 若是弹框建议 watch 参数: visible.sync==true 时), 请求方法如下
- // 获取列表
- findLists() {
- const tbJson = JSON.stringify({
- length: 10,
- start: 1,
- searchBy: [],
- orderBy: {}
- })
- this.$axios.post('/api/files/list', {
- // 获取列表需要参数
- tbJson,
- fid: this.pId
- }).then(res => {
- if (res.status === 200) {
- this.fileList = Object.assign([], [])
- // 后台返回数据需要做处理, 才能正常展示
- res.data.list.forEach((l) => {
- const obj = {
- name: l.fname,
- url: process.env.vue_APP_BASE_API + '/' + l.fpath
- }
- this.fileList.push(obj)
- })
- this.defaultfileList = Object.assign([], res.data.list)
- } else {
- this.$mess.messagePrompt(res.message, 'error', true, false)
- }
- }).catch(() => {
- })
- },
2, 上传图片或者文档
上传时, 需要上传地址, 头信息, 额外参数等信息带给后台, 这些参数之类的还好 ele 都给封装过了, 基于组件就能完成
- <el-upload
- :accept="accept"// 接受上传的 [文件类型]
- :action="upload"// 必选参数, 上传的地址
- :data="datas()"// 上传时附带的额外参数
- :headers="headers()"// 设置上传的请求头部
- :multiple="multiple"
- :on-remove="handleRemove"// 文件列表移除文件时的钩子
- :on-success="handleSuccess"// 文件上传成功时的钩子
- :on-preview="handlePictureCardPreview"// 点击文件列表中已上传的文件时的钩子
- :disabled="disabledInput"
- list-type="picture"// 文件列表的类型
- :before-remove="beforeRemove"// 删除文件之前的钩子
- :file-list.sync="fileList"// 上传的文件列表,
- >
- <el-button v-if="!isRead" size="small" type="primary" icon="el-icon-upload" :plain="plain" style="float: left">
新增附件
- </el-button>
- </el-upload>
3, 删除爬坑 (方法很笨, 不建议学习, 有好的办法多多交流)
测试发现, upload 几个事件的返回值是组件处理后的数据 (数据格式不是列表的数据格式). 接下来就要忙着找 ID 找下标来做删除.....
思路: 因为 uid 是数据的唯一标识, 渲染列表后将列表数据存起来, 点击删除某一项时取其 uid 进行匹配, 从而删除.
1562486902(1).jpg
1562487032(2).jpg
4, 附上完整组件 (部分是因为业务需求, 可忽略....)
- <template>
- <div>
- <el-dialog
- v-if="dialogVisible"
- :close-on-click-modal="false"
- :visible.sync="dialogVisible"
- width="550px"
- title="附件列表"
- >
- <div class="upload-container" style="max-height:500px;overflow-y:auto;">
- <el-dialog :close-on-click-modal="false" :visible.sync="dialogVisibleImg" :title="ImgName" append-to-body>
- <img width="100%" :src="dialogImageUrl" alt="">
- </el-dialog>
- <el-upload
- class="uploadShow"
- :accept="accept"
- :action="upload"
- :data="datas()"
- :headers="headers()"
- :multiple="multiple"
- :on-remove="handleRemove"
- :on-success="handleSuccess"
- :on-preview="handlePictureCardPreview"
- :disabled="disabledInput"
- list-type="picture"
- :before-remove="beforeRemove"
- :file-list.sync="fileList"
- >
- <el-button v-if="!isRead" size="small" type="primary" icon="el-icon-upload" :plain="plain" style="float: left">
新增附件
- </el-button>
- </el-upload>
- </div>
- </el-dialog>
- </div>
- </template>
- <script>
- import dialogMixins from '@/mixins/diolog'import {
- getToken
- }
- from '@/utils/auth'export
- default {
- components:
- {},
- mixins: [dialogMixins],
- props: {
- multiple: {
- type: Boolean,
- default:
- true
- },
- isRead: {
- type: Boolean,
- default:
- false
- },
- disabledInput: {
- type: Boolean,
- default:
- false
- },
- accept: {
- type: String,
- default:
- ''
- },
- pId: {
- type: String,
- default:
- ''
- },
- plain: {
- type: Boolean,
- default:
- false
- }
- },
- data() {
- return {
- defaultfileList: [],
- innerfileList: [],
- // 删除之前数据
- fileList: [],
- // 删除之后数据 (渲染数据)
- dialogVisibleImg: false,
- dialogImageUrl: '',
- ImgName: ''
- }
- },
- computed: {
- upload() {
- return`$ {
- process.env.VUE_APP_BASE_API
- }
- /api/files / upload`
- // return (process.env.NODE_ENV === 'production' ? process.env.BASE_URL : '/api') + '/api/files/upload'
- }
- },
- watch: {
- dialogVisible(e) {
- if (e) {
- this.findLists()
- }
- }
- },
- methods: {
- // 获取列表
- findLists() {
- const tbJson = JSON.stringify({
- length: 10,
- start: 1,
- searchBy: [],
- orderBy: {}
- }) this.$axios.post('/api/files/list', {
- tbJson,
- fid: this.pId
- }).then(res = >{
- if (res.status === 200) {
- this.fileList = Object.assign([], []) res.data.list.forEach((l) = >{
- const obj = {
- name: l.fname,
- url: process.env.VUE_APP_BASE_API + '/' + l.fpath
- }
- this.fileList.push(obj)
- }) this.defaultfileList = Object.assign([], res.data.list)
- } else {
- this.$mess.messagePrompt(res.message, 'error', true, false)
- }
- }).
- catch(() = >{})
- },
- headers() {
- const object = {
- Authorization: getToken('token')
- }
- return object
- },
- datas() {
- const pId = {
- fid: this.pId
- }
- return pId
- },
- beforeRemove(file, fileList) {
- // 删除提醒
- return this.$mess.confirm().then(() = >{
- this.innerfileList = JSON.parse(JSON.stringify(fileList))
- })
- },
- handleSuccess(res, file, fileList) {
- this.defaultfileList.push({
- id: res.data
- }) this.fileList = Object.assign([], fileList) this.innerfileList = Object.assign([], fileList) this.$emit('update:fileList', fileList)
- },
- handleRemove(file, fileList) {
- const index = this.innerfileList.findIndex(el = >{
- return file.uid === el.uid
- }) this.$axios.post('/api/files/del', {
- ids: this.defaultfileList[index].id
- }).then(res = >{
- if (res.status === 200) {
- this.innerfileList.splice(index, 1) this.defaultfileList.splice(index, 1) this.fileList.splice(index, 1) this.$message({
- type: 'success',
- message: '操作成功'
- })
- } else {
- this.$mess.messagePrompt(res.message, 'error', true, false)
- }
- }).
- catch(() = >{})
- },
- handlePictureCardPreview(file) {
- const arr = ['gif', 'jpg', 'jpeg', 'png', 'PNG', 'JPG', 'GIF'] const s = arr.filter(el = >{
- return file.url.includes(el)
- }) if (s.length) {
- this.dialogImageUrl = file.url this.dialogVisibleImg = true
- } else {
- Windows.open(file.url)
- }
- }
- }
- }
- </script>
- <style scoped>
- .uploadShow{ }
- </style>
来源: http://www.jianshu.com/p/a107617bb309