VUE最轻量上传组件
组件代码
<template> <div :class="cssClass" style="position:relative"> <input type="file" :accept="extend?extend:'*'" style="position:absolute;left:0;top:0;width:100%;min-height:30px;opacity:0"> <slot></slot> </div> </template> <script> export default{ props: ['url','maxWidth','params', 'cssClass','extend'], data: {filename:''}, mounted(){ var _this = this; _this.$el.querySelector('input').addEventListener('change',function(){ _this.prepare(); }); _this.$el.addEventListener('imageResized', function(e){ _this.$emit('preview', e.detail.url); _this.upload(e.detail.blob); }); }, methods: { resize: function(file){ var _this = this; var dataURLToBlob = function(dataURL){ var BASE64_MARKER = ';base64,'; if(dataURL.indexOf(BASE64_MARKER) == -1){ var parts = dataURL.split(','); var contentType = parts[0].split(':')[1]; var raw = parts[1]; return new Blob([raw], {type: contentType}); } var parts = dataURL.split(BASE64_MARKER); var contentType = parts[0].split(':')[1]; var raw = window.atob(parts[1]); var rawLength = raw.length; var uInt8Array = new Uint8Array(rawLength); for (var i = 0; i < rawLength; ++i) { uInt8Array[i] = raw.charCodeAt(i); } return new Blob([uInt8Array], {type: contentType}); } var reader = new FileReader(); reader.onload = function(readerEvent){ var image = new Image(); image.onload = function(imageEvent){ var canvas = document.createElement('canvas'),max_size = _this.maxWidth, width = image.width, height = image.height; if(width > height){ if(width > max_size){ height *= max_size / width; width = max_size; } }else{ if(height > max_size){ width *= max_size / height; height = max_size; } } canvas.width = width; canvas.height = height; canvas.getContext('2d').drawImage(image, 0, 0, width, height); var dataUrl = canvas.toDataURL('image/jpeg'); var resizedImage = dataURLToBlob(dataUrl); _this.$el.dispatchEvent(new CustomEvent('imageResized',{detail:{blob: resizedImage, url: dataUrl}})); } image.src = readerEvent.target.result; } reader.readAsDataURL(file); }, prepare(){ var file = this.$el.querySelector('input').files[0]; this.filename = file.name; if(this.extend){ var ext = this.filename.toLowerCase().split('.'); ext = ext[ext.length-1]; var existExtend=false; for(var i=0;i<this.extend.length;i++){ if(ext==this.extend[i]){ existExtend=true;break; } } if(!existExtend){ //this.$layer.msg('只支持上传文件格式:'+this.extend.join());return; } } if(file.type.match(/image.*/) && this.maxWidth){ this.resize(file) }else{ this.upload(file); } }, upload(file){ var formData = new FormData(),xhr = new XMLHttpRequest(); formData.append('file', file, this.filename); xhr.open('POST', this.url); xhr.withCredentials = true; xhr.upload.addEventListener('progress', (evt)=>{ this.$emit('progress', Math.round(evt.loaded/evt.total*100)); }); xhr.onload = ()=>{ if(xhr.status === 200){ this.$emit('success', JSON.parse(xhr.responseText), this.params); this.$emit('input', JSON.parse(xhr.responseText).data[0]); }else { console.log(xhr) } }; xhr.send(formData); } } } </script>
调用方法
<light-upload class="btn btn-primary" maxWidth="800" :url="API+'/user/upload?type=historyLog'" @success="onUploadFileAdd"><a href="javascript:;" >上传</a></light-upload>