因为element ui 上传组件的代码很长,在项目中关于上传的代码过于冗余,因此我二次封装了一个上传附件的组件:
项目中使用:
1 <!-- 附件 --> 2 <el-form-item label="附件信息" prop="accessory" style="position: relative" class="ml30"> 3 <e-upload 4 v-model="accessory" 5 :limit="3" 6 :acceptData="{ maxsize: 50 * 1024 * 1024 }" 7 accept=".doc,.docx,.xls,.xlsx,.pdf" 8 @change="onFileChange" 9 > 10 </e-upload> 11 <span class="tip">(注:支持word、pdf、excel,单个文件大小不超过50M,最多上传3个文件)</span> 12 </el-form-item>
1 onFileChange(fileList) { // 该方法就可以拿到当前组件上传的文件数据 2 this.model.accessory = JSON.stringify(fileList) 3 }
注册组件 src/components/index.js:
1 import EUpload from './EUpload' 2 export default { 3 install(Vue) { 4 Vue.component('EUpload', EUpload) 5 } 6 }
main.js引入自定义组件:
import Components from '@/components/index' Vue.use(Components)
组件 EUpload.vue 全部代码:
1 <template> 2 <!-- 上传附件组件,上传完后支持点击下载 --> 3 <div> 4 <el-upload 5 :action="uploadApi()" 6 :data="acceptData" 7 :limit="limit" 8 multiple 9 :accept="accept" 10 :file-list="fileList" 11 :on-exceed="handleExceed" 12 :on-success="(response, file, fileList) => handleSuccess(response, file, fileList)" 13 :before-upload="file => beforeUpload(file)" 14 > 15 <el-button size="small" type="primary">点击上传</el-button> 16 <!-- 通过插槽定义方法 --> 17 <div slot="file" slot-scope="{ file }"> 18 <a class="el-upload-list__item-name" @click="handleDownLoad(file)"> <i class="el-icon-document"></i>{{ file.name }} </a> 19 <i class="el-icon-close" @click.stop="handleRemove(file)"></i> 20 <i class="el-icon-close-tip">按 delete 键可删除</i> 21 </div> 22 </el-upload> 23 </div> 24 </template> 25 26 <script> 27 const uidGenerator = () => { 28 return '-' + parseInt(Math.random() * 10000 + 1, 10) 29 } 30 31 export default { 32 name: 'EUpload', 33 props: { 34 value: { 35 type: [String, Array], 36 required: false 37 }, 38 // 文件类型 39 accept: { 40 type: String, 41 default: '.doc,.docx,.xls,.xlsx,.pdf' 42 }, 43 // 上传时附带的额外参数 44 acceptData: { 45 type: Object, 46 default: () => { 47 return { 48 maxsize: 1024 * 1024 * 20, // 限制文件大小 49 maxsize_text: '20M', // 上传文件超过大小时的提示语 50 disabledDownload: false, 51 disabledRemove: false 52 } 53 } 54 }, 55 // 提示 56 tip: { 57 type: String, 58 default: '' 59 }, 60 // 最大数量 61 limit: { 62 type: Number, 63 default: 10 64 } 67 }, 68 watch: { 69 value: { // 编辑/详情时,回显触发,生成业务可以下载的 url 70 handler(val, oldValue) { 71 this.initFileList(val) 72 }, 73 // 立刻执行handler 74 immediate: true 75 } 76 }, 77 data() { 78 return { 79 fileList: [] 80 } 81 }, 82 methods: { 83 // 将业务数据回显给组件 84 initFileList(array) { 85 if (!array || array.length == 0) { 86 this.fileList = [] 87 return 88 } 89 let fileList = [] 90 let arr = array 91 for (let a = 0; a < arr.length; a++) { 92 let url = this.getFileAccessHttpUrl(arr[a].filePath) // 生成业务中支持下载的文件路径,该方法可根据项目不同进行修改 93 fileList.push({ 94 uid: uidGenerator(), 95 name: arr[a].fileName, 96 status: 'done', 97 url: url, 98 response: { 99 status: 'history', 100 message: url 101 } 102 }) 103 } 104 this.fileList = fileList 105 }, 106 // 添加前缀, /dispatch 是项目中支持点击下载的文件前缀,需要加上 107 getFileAccessHttpUrl(url) { 108 if (url.indexOf('/dispatch') > -1) { 109 return url 110 } else { 111 return '/dispatch' + url 112 } 113 }, 114 // 上传文件地址 115 uploadApi() { 116 return '/dispatch/upload' 117 }, 118 // 文件大小限制 119 beforeUpload(file) { 120 const isLessThanMaxSize = file.size < this.acceptData.maxsize 121 if (!isLessThanMaxSize) { 122 this.$toast(`上传文件大小不能超过${this.acceptData.maxsize_text}!`) 123 } 124 return isLessThanMaxSize 125 }, 126 // 文件个数限制 127 handleExceed() { 128 this.$toast(`当前限制最多上传 ${this.limit} 个文件!`) 129 }, 130 // 上传成功 131 handleSuccess(response, file, fileList) { 132 if (response.code == 200) { 133 this.$toast('上传成功') 134 let attachment = fileList.map(item => { 135 let url = '' 136 if (item.status === 'success' && item.response) { 137 url = item.response.data || '' 138 } else { 139 if (item.url) { 140 url = item.url || '' 141 } 142 } 143 return { name: item.name, url: url, uid: item.uid } 144 }) 145 this.fileList = JSON.parse(JSON.stringify(attachment)) 146 attachment = attachment.map(item => { 147 return { 148 fileName: item.name, 149 filePath: item.url, 150 uid: item.uid 151 } 152 }) 153 // 回显给业务 154 this.$emit('change', attachment) 155 } 156 }, 157 // 删除 158 handleRemove(file) { 159 let index 160 this.fileList.find((item, idx) => { 161 if (item.uid === file.uid) { 162 index = idx 163 return 164 } 165 }) 166 if (typeof index !== 'undefined') { 167 this.fileList.splice(index, 1) 168 } 169 // 回显给业务 170 this.$emit('change', this.fileList) 171 },
172 // 点击下载文件 173 handleDownLoad(item) { 174 const uploadUrl = process.env.VUE_APP_DOWNLOAD_URL + this.getFileAccessHttpUrl(item.url) 175 if (this.isAndroid() && window.android) { // 移动端下载方法 176 window.android.updateFile(uploadUrl, item.name) 177 } else { 178 window.location.href = uploadUrl 179 } 180 }, 181 // 判断机型是android 182 isAndroid() { 183 const u = navigator.userAgent 184 const isAndroid = u.indexOf('Android') > -1 || u.indexOf('Adr') > -1 // 判断android 185 return isAndroid 186 } 187 } 188 } 189 </script>
标签:封装,url,fileList,element,item,ui,file,return,上传 From: https://www.cnblogs.com/buluzombie/p/16735394.html