基于element-ui upload进行二次封装,可拖拽上传列表

  1 <template>
  2     <div>
  3         <el-upload
  4           ref="upload"
  5           class="upload"
  6           :drag="drag"
  7           :disabled="disabled"
  8           :multiple="multiple"
  9           :auto-upload="autoUpload"
 10           :show-file-list="showFileList"
 11           :with-credentials="withCredentials"
 12           
 13           :limit="limit"
 14           :accept="accept"
 15           :list-type="listType"
 16           
 17           :name="name"
 18           :action="action"
 19           :data="extraParams"
 20           :headers="requestHeaders"
 21           
 22           :http-request="isRequest ? handleHttpRequest : undefined"
 23 
 24           :on-error="handleError"
 25           :on-exceed="handleExceed"
 26           :on-change="handleChange"
 27           :on-remove="handleRemove"
 28           :on-success="hendleSuccess"
 29           :on-preview="handlePreview"
 30           :on-progress="handleProgress"
 31 
 32           :before-upload="handleBeforeUpload"
 33           :before-remove="handleBeforeRemove"
 34 
 35 
 36           :file-list="fileList"
 37         >
 38           <slot></slot>
 39           <slot name="trigger"></slot>
 40           <div slot="tip">
 41             <slot name="tip"></slot>
 42           </div>
 43           <div v-if="isSlotFile" slot="file" slot-scope="scope">
 44             <slot name="file" v-bind="scope"></slot>
 45           </div>
 46         </el-upload>
 47     </div>
 48 </template>
 49 
 50 <script>
 51 import Sortable from 'sortablejs';
 52 export default {
 53     name: 'customUpload',
 54     props: {
 55         // 属性
 56         isRequest: {
 57             type: Boolean,
 58             default: () => false
 59         },
 60         isSlotFile: {
 61             type: Boolean,
 62             default: () => false
 63         },
 64         drag: {
 65             type: Boolean,
 66             default: () => false
 67         },
 68         sortable: {
 69             type: Boolean,
 70             default: () => false
 71         },
 72         disabled: {
 73             type: Boolean,
 74             default: () => false
 75         },
 76         multiple: {
 77             type: Boolean,
 78             default: () => false
 79         },
 80         autoUpload: {
 81             type: Boolean,
 82             default: () => true
 83         },
 84         showFileList: {
 85             type: Boolean,
 86             default: () => true
 87         },
 88         withCredentials: {
 89             type: Boolean,
 90             default: () => false
 91         },
 92         // 文件限制
 93         limit: {
 94             type: Number,
 95             default: () => 1
 96         },
 97         maxSize: {
 98             type: Number,
 99             default: () => 100 * 1024
100         },
101         accept: {
102             type: String,
103             default: () => '.jpg,.JPG,.png,.PNG'
104         },
105         listType: {
106             type: String,
107             default: () => 'text'
108         },
109         imgWidth: {
110           type: Number,
111           default: () => 0
112         },
113         imgHeight: {
114           type: Number,
115           default: () => 0
116         },
117 
118         // 文件上传参数
119         name: {
120             type: String,
121             default: () => 'file'
122         },
123         action: {
124             type: String,
125             default: () => ''
126         },
127         extraParams: {
128             type: Object,
129             default: () => ({})
130         },
131         requestHeaders: {
132             type: Object,
133             default: () => ({})
134         },
135 
136         // 上传事件
137         onError: { type: Function, default: function () { } },
138         onExceed: { type: Function, default: function () { } },
139         onChange: { type: Function, default: function () { } },
140         onRemove: { type: Function, default: function () { } },
141         onSuccess: { type: Function, default: function () { } },
142         onPreview: { type: Function, default: function () { } },
143         onProgress: { type: Function, default: function () { } },
144         beforeUpload: { type: Function, default: function () { return true; } },
145         beforeRemove: { type: Function, default: function () { return true; } },
146 
147         httpRequest: { type: Function, default: function () { } },
148 
149         customList: {
150             type: Array,
151             default: () => []
152         }
153     },
154     data() {
155         return {
156             fileList: []
157         }
158     },
159     watch: {
160         fileList: {
161             deep: true,
162             immediate: true,
163             handler(val) {
164                 this.$emit('update:customList', val);
165             }
166         },
167         customList: {
168             deep: true,
169             immediate: true,
170             handler(val) {
171                 if(!this.fileList.length) {
172                     this.fileList = val;
173                 }
174             }
175         }
176     },
177     computed: {
178 
179     },
180     mounted() {
181         let _this = this;
182         if (this.sortable) {
183             var list = this.$el.querySelector('.el-upload-list');
184             Sortable.create(list, {
185                 onEnd: (ev) => {
186                     let arr = _this.fileList;
187                     arr[ev.oldIndex] = arr.splice(ev.newIndex, 1, arr[ev.oldIndex])[0];
188                 },
189             });
190         }
191     },
192     methods: {
193         // 清空
194         clearFiles() {
195             this.$refs['upload']['clearFiles']();
196         },
197 
198         // 提交
199         submit() {
200             this.$refs['upload']['submit']();
201         },
202 
203         // 取消
204         abort() {
205             this.$refs['upload']['abort']();
206         },
207 
208 
209         // 文件上传事件
210         handleError(err, file, fileList) {
211             this.onError(err, file, fileList);
212         },
213 
214         handleExceed(files, fileList) {
215             this.onExceed(files, fileList);
216         },
217 
218         handleChange(file, fileList) {
219             this.onChange(file, fileList);
220         },
221 
222         handleRemove(file, fileList) {
223             this.fileList = fileList;
224             this.onRemove(file, fileList);
225         },
226 
227         hendleSuccess(response, file, fileList) {
228             response.name = file.name;
229             response.url = file.url;
230             this.fileList.push(response);
231             this.onSuccess(response, file, fileList);
232         },
233 
234         handlePreview(file) {
235             this.onPreview(file);
236         },
237 
238         handleProgress(event, file, fileList) {
239             this.onProgress(event, file, fileList);
240         },
241 
242         // 文件上传前操作
243         handleBeforeUpload(file) {
244             let accept = this.accept;
245             let maxSize = this.maxSize;
246             let isMaxSize = file.size < maxSize;
247             let isOkExt = accept.indexOf(file.name.substring(file.name.lastIndexOf('.'))) >= 0;
248 
249             if (!isOkExt) {
250                 accept = accept.replace(/\,\./g, '/');
251                 accept = accept.replace('.', '');
252                 this.$message.error(`只能上传${accept}格式的文件`);
253                 return false;
254             }
255 
256             if (!isMaxSize) {
257                 const { size, sizeType } = this.sizeTypes(maxSize);
258                 this.$message.error(`上传文件大小不能超过${size}${sizeType}`);
259                 return false;
260             }
261 
262             if(this.imgWidth && this.imgHeight) return this.scaling({ file, width: this.imgWidth, height: this.imgHeight });
263 
264             return this.beforeUpload(file);
265         },
266 
267         handleBeforeRemove(file) {
268             return this.beforeRemove(file);
269         },
270 
271         // 自定义上传
272         handleHttpRequest(files) {
273             this.httpRequest(files);
274         },
275         
276         // 文件大小类型
277         sizeTypes(maxSize) {
278             if (maxSize >= 1024 * 1024) {
279                 let size = parseInt(maxSize / 1024 / 1024);
280                 return {
281                     size,
282                     sizeType: 'M'
283                 }
284             } else if (maxSize >= 1024) {
285                 const size = parseInt(maxSize / 1024);
286                 return {
287                     size,
288                     sizeType: 'kb'
289                 }
290             } else {
291                 return {
292                     size: maxSize,
293                     sizeType: 'b'
294                 };
295             }
296         },
297 
298 
299         // 对比图片比例
300         scaling({ file, width, height }) {
301             return new Promise(function (resolve, reject) {   //upload内部需要一个promise,简单的return出false并没有什么用
302                 let _URL = window.URL || window.webkitURL;
303                 let image = new Image();
304                 image.onload = function () {
305                     let valid = image.width === width && image.height === height;
306                     valid ? resolve(true) : reject(false);
307                 };
308                 image.src = _URL.createObjectURL(file);    //onload是异步加载,所以一定要在onload后在执行判断图片尺寸
309             }).then(
310                 () => {
311                     return file;
312                 },
313                 () => {
314                     this.$message.error("请上传正确的图片比例");
315                     return Promise.reject(false);
316                 }
317             );
318         }
319 
320 
321     }
322 }
323 </script>

 

posted @ 2022-10-18 10:55  杨景贵  阅读(173)  评论(0)    收藏  举报