preface

When I was working on projects, I always encountered the need to upload attachments, no matter on the Web or mobile end. Of course, there are a lot of third-party plugins on the web, such as vUE based Element-UI upload attachments, but it is difficult to modify with third-party plugins. So I encapsulated a method to upload attachments, write their own method, use and modify it is very cool, ha ha

Making the address

Github.com/lirongrong/…

demo

function

  1. The uploaded attachment can be divided into two formats: picture and non-picture
  2. Uploaded attachments are compiled into base64-bit format
  3. Compress the uploaded images

HTML

Bind the change event with vUE

<input type="file" multiple="multiple" v-on:change="chooseImage" placeholder="Upload picture" />
Copy the code

JS

ChooseImage can get information about uploaded attachments

chooseImage(e){
    var files = e.target.files;
}
Copy the code

Traverse files to determine the size and format of uploaded attachments

var defaults = {
    folder: "default",
    size: 3,
    type: ['image'.'word'.'pdf'.'zip'.'rar'.'sheet'.'text'.'log'.'psd'], // maxWidth: Number, // maxWidth: Number, // maxHeight: Number, // maxHeight: Numberfalse,
    beforeSend: false};for(var i = 0; i < files.length; i++) { var file = files[i]; // Attachments larger than 3M are prohibitedif (file.size > defaults.size * 1024 * 1024) {
        that.showToast("Document [" + file.name + ">" + defaults.size + "M!");
        return; } // Not in the upload format range, is prohibited var valiType =false;
    for (var i = 0; i < defaults.type.length; i++) {
       var item = defaults.type[i];
       if (file.type.indexOf(item) >= 0) {
           valiType = true;
           break; }}if(! valiType) { that.showToast("Incorrect file type!");
       return; }... }Copy the code

Then I used HTML5’s FileReader method:

The FileReader object allows a Web application to asynchronously read the contents of a File (or raw data buffer) stored on the user’s computer, using a File or Blob object to specify which File or data to read.

Then the three for loops above… The place to live here is:

Uploaded attachments are classified into pictures and non-pictures. The purpose of this classification is to compress the image when uploading the image, so that the image is too wide or too high to occupy the space of the server

var reader = new FileReader(); 
var type = file.type.split('/') [0]; reader.readAsDataURL(file); reader.onloadstart =function() {// To add some events or effects before uploading, such as loading... That. Loading ='loading';
};
reader.onloadend = function(){// remove loading effect that.loading =' '; // When the attachment format is not an imageif(type! ='image') that.model.fileList.push(file); Var dataURL = this.result; var imaged = new Image(); imaged.src = dataURL; imaged.onload =function() { var img = this; Var getImg = that.getbase64Image (img,{maxWidth:1000, maxHeight:1000}); that.model.imgList.push({ src:getImg.dataURL }) }; }Copy the code

All attachments are in the Data Model, and here are the bindings for the page

<! <ul> <li class="flex flex_align_center" style="padding:6px 0;" v-for="(item,index) in model.fileList" :key="index">
        <span class="flex_item">{{item.name}}</span>
        <a title="Delete" class="ml10" @click="deleteFile(index)"</a> </li> </ul> <! --> <ul id="preview" class="flex flex_wrap">
    <li v-for="(item,index) in model.imgList" :key="index" style="flex-basis: 20%;" class="pr">
        <img :src="item.src" alt=""/>
        <i class="iconfont icon-shanchu pa" @click="deleteImg(index)"></i>
    </li>
</ul> 
<div>{{loading}}</div>
Copy the code

You may have noticed the getBase64Image method for compressing images. This is a method that I encapsulate myself. I compress images by defining the maximum width and maximum height

Careful friends may find that at the end of the demo picture, the pixel I uploaded was 3543 * 5315. After uploading, the size of the picture was equally compressed to 667 * 1000. Since the maximum width and height I set were 1000, the corresponding width and height would be equally reduced

/** * getBase64Image:function(img,options){
    var defaults = {
        maxWidth : Number,
        maxHeight : Number
    };
    if(options ! = undefined && options ! = null){ defaults = $.extend(defaults,options) }; Canvas = document.createElement('canvas');
    var context = canvas.getContext('2d'); Var originWidth = img.width; var originHeight = img.height; Var maxWidth = defaults.maxWidth, maxHeight = defaults.maxHeight; Var targetWidth = originWidth, targetHeight = originHeight; // The image size exceeds the 400x400 limitif(originWidth > maxWidth || originHeight > maxHeight) {
        if(originWidth/originHeight > maxWidth/maxHeight) { targetHeight = Math.round(maxWidth * (originHeight / originWidth)); }else{ targetHeight = maxHeight; targetWidth = Math.round(maxHeight * (originWidth / originHeight)); } // Canvas to scale canvas. Width = targetWidth; canvas.height = targetHeight; // Clear the canvas context.clearRect(0, 0, targetWidth, targetHeight); Context. DrawImage (img, 0, 0, targetWidth, targetHeight); /* The first argument is to create the img object; The second argument is the upper-left coordinate, and the next two are the width and height of the canvas area */ // compressed image base64 URL /* Cancanvas. ToDataURL (mimeType, qualityArgument),mimeType defaults to'image/jpeg'; DataURL = canvas.todataurl (*/ dataURL = canvas.todataurl)'image/jpeg'); Var base64 = dataurl.substr (dataurl.indexof (",") + 1);
    return {dataURL,base64};
},
Copy the code

Add an additional hint method

/** * showToast:function (msg) {
    var objToast = "<div class='rr_toast'>" + msg + "</div>"
    $(document.body).append(objToast);
    setTimeout(function() {$('.rr_toast').remove(); }}, 1000)Copy the code

To optimize

  1. Multiple images cannot be uploaded at the same time. It needs to be improved
  2. Upload loading effect needs to be optimized, now only simple loading text show and hide
  3. Preview picture
  4. Non-image attachment preview

conclusion

The complete code above is on Github, you can directly download and run, welcome to correct the mistakes.