Hi, I wonder if you are like me? Ever wonder how elemental-UI file drag and upload works? How to monitor real-time upload progress? Let’s do it today. I don’t care if it’s low. Ha ha

1. Apis for dragging

1.1 Trigger event on drag target (source element):

  1. Ondragstart – Triggered when the user starts dragging elements
  2. Ondrag – Triggered while the element is dragging
  3. Ondragend – Triggered when the user finishes dragging the element

1.2 Events triggered when releasing the target:

  1. Ondragenter – This event is triggered when a mouse-dragged object enters its container scope
  2. Ondragover – This event is triggered when a dragged object is dragged within the scope of another object container
  3. Ondragleave – This event is triggered when an object dragged by the mouse leaves its container scope
  4. Ondrop – This event is triggered when the mouse key is released during a drag

An onDrag event is emitted every 350 milliseconds as you drag an element

1.3 Implement element drag and drop

<p draggable="true" >You can drag properties after setting them</p>
Copy the code

Now that we know the basic API, let’s do an example of drag-and-upload: let’s go to the last image, no image, no power, haha

<template>
    <div class="index">
        <div class="index-box">
            <! -- Local upload progress -->
            <div class="index-progress">
                <div class="index-progress-name">Local upload Progress:</div>
                <div class="index-progress-number">
                    <el-progress :percentage="scale" :status="scaleName ? scaleName : null "></el-progress>
                </div>
            </div>
            <! -- Drag area -->
            <div class="index-drag" 
                ref="updataDrag"
                @dragover="updataDragover" 
                @dragenter="updataDragenter"
                @dragleave="updataDragleave"
                @drop="updateDrop">

                <div class="index-drag-iconBox">
                    <span class="el-icon-upload"></span>
                </div>
                <div class="index-drag-message">
                    <span class="index-drag-message-titles">Drag the file here, or</span>
                    <label for="file" class="index-drag-message-label">
                        <input class="index-drag-message-input" type="file" id="file" name="file" @change="manualChange" />
                        <span class="index-drag-message-manual">Click on the upload</span>
                    </label>
                </div>
            </div>
            <! -- Local upload progress -->
            <div class="index-progress">
                <div class="index-progress-name">Server upload progress:</div>
                <div class="index-progress-number">
                    <el-progress :percentage="network" :status="networkName ? networkName : null "></el-progress>
                </div>
            </div>
        </div>
        
    </div>
</template>

<script>
import axios from 'axios'

export default {
    data(){
        return {
            scale: 0 ,// Local upload progress
            scaleName: null.network: 0 , // Network upload
            networkName: null}},methods: {// This event is emitted when the dragged object is dragged within the scope of another object container
        updataDragover(ev){
            // Note the key here
            ev.preventDefault()
        },
        // This event is emitted when a mouse-dragged object enters its container scope
        updataDragenter(){
            this.scaleName = null
            // When the element is dragged into the target area, the target border turns blue
            this.$refs.updataDrag.style.borderColor = '#4B87FF'
            this.$refs.updataDrag.style.background = '#F7F7F8'
        },
        // This event is emitted when a mouse-dragged object is out of its container scope
        updataDragleave(){
            // When the dragged element leaves the target area, the target border becomes gray
            this.$refs.updataDrag.style.borderColor = '#A3A3A3'
            this.$refs.updataDrag.style.background = '#ffffff'
        },
        // This event is emitted when the mouse key is released during a drag
        updateDrop(ev){
            
            let oFile = ev.dataTransfer.files[0];
                this.readerFile(oFile)

                The default event prevents the browser from opening drag files automatically
            ev.preventDefault()
        },
        // Manually upload files
        manualChange(ev){
            let oFile = ev.target.files[0]
                this.readerFile(oFile)
        },
        // Read the file
        readerFile(oFile){
            let This = this
            var reader = new FileReader();
            // The read succeeded
            reader.onload = function(ev){
                // The following file types are not accurate, only the entry level, the accurate judgment should be directly judged Buffer(not described here)
                / / Base64
                let txt = ev.target.result;
                // Semicolon position
                let semicolonIndex = txt.indexOf('; ')
                // Colon position
                let colonIndex = txt.indexOf(':')
                // Text type
                let txtType = txt.slice(colonIndex + 1,semicolonIndex)
                // Detail type
                let types = ' '
                let format = ' '

                // Under Mac is ('\')? Ha ha
                let txtTypeArr = txtType.split('/')
                    if(txtTypeArr[0= = ='image') {console.log('Picture: type is' + txtTypeArr[1])
                        // Base64 transfers image files
                        let images = This.baseImage(txt,'abc.' + txtTypeArr[1])

                         let params = new FormData()
                            params.append('file',images)  // 

                        This.submitUpdata(params)
                    }
                    if(txtTypeArr[0= = ='video') {console.log('Video: Type is' + txtTypeArr[1])

                        let params = new FormData()
                            params.append('file',oFile)  // 

                        This.submitUpdata(params)
                    }


            };
            reader.onloadstart = function(){
                console.log('Start reading');
                This.scaleName = null
            };
            reader.onloadend = function(){
                console.log('End of read');
                This.scaleName = 'success'
            };
            reader.onabort = function(){
                console.log('interruption');
                This.scaleName = 'exception'
            };
            reader.onerror = function(){
                console.log('Read failed');
                This.scaleName = 'warning'
            };
            reader.onprogress = function(ev){
            var scale = ev.loaded/ev.total;
                if(scale>=0.5){
               
                reader.abort();
                }
                // oM.value = scale*100;
                This.scale = parseInt(scale*100)
                console.log(This.scale)
            };
            reader.readAsDataURL(oFile); // ,'base64'
        },
        // Base64 transfers images
        baseImage(dataurl, filename) {
            let arr = dataurl.split(', '), mime = arr[0].match(/ : (. *?) ; /) [1],
                bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
                while(n--){
                    u8arr[n] = bstr.charCodeAt(n);
                }
            return new File([u8arr], filename, {type:mime});
        },
        / / upload
        submitUpdata(file){
            
            let This = this
            This.networkName = null
            axios({
                method: 'post'.url: 'https://jsonplaceholder.typicode.com/posts/'.data: file,
                headers: {'Content-Type': 'multipart/form-data'},
                onUploadProgress:function(progress){
                    // Upload the processing progress event
                    
                    let network = parseInt((progress.loaded/progress.total) * 100) 

                        This.network = network
                        console.log(This.network)
                        if(progress.loaded == progress.total){
                            This.networkName = 'success'
                        }else{
                            This.networkName = null}},onDownloadProgress:function(progress){
                    // Process progress events for the download
                }
            })
            .then(res= > {

                // The status code is 201. // The status code is 201
                if(res.status >= 200 && res.status <= 206){
                   This.networkName = 'success'
                }
                if(res.status >= 400){
                   This.networkName = 'exception'}})}}}</script>

<style scoped>
.index-box{
    width: 100%;
    height: auto;
    padding: 15px;
    box-sizing: border-box;
}
.index-progress{
    width: 450px;
    height: 60px;
    /* background: chartreuse; * /
    margin: 0 auto;
    margin-bottom: 15px;
    display: flex;
    justify-content: space-between;
}
.index-progress-name{
    width: 120px;
    height: 60px;
    font-size: 14px;
    font-weight: bold;
    line-height: 60px;
    /* background: chocolate; * /
}
.index-progress-number{
    flex: 1;
    height: 60px;
    padding: 22px;
    box-sizing: border-box;
}
.index-drag{
    width: 450px;
    height: 300px;
    border: 2px dashed;
    border-color: #A3A3A3;
    border-radius: 5px;
    margin: 0 auto;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    flex-wrap: wrap;
}
.index-drag-iconBox{
    width: 100%;
    height: 60px;
    /* background: brown; * /
    text-align: center;
    font-size: 50px;
    line-height: 60px;
    color: # 606266;
}
.index-drag-message{
    width: 100%;
    height: 50px;
    line-height: 50px;
    text-align: center;
}
.index-drag-message-titles{
    font-size: 14px;
    color: # 606266;
}
.index-drag-message-manual{
    font-size: 14px;
    color: #4B87FF;
    cursor: pointer;
}
.index-drag-message-label{
    width: 120px;
    height: 50px;
    height: auto;
    position: relative;
    overflow: hidden;
    /* background: chartreuse; * /
    
}
.index-drag-message-input{
    position: absolute;
    left: -100px;
    top: -100px;
    z-index: -1;
    display: none;
}
</style>
Copy the code

expand

  1. Should you also determine whether to block the extension of other files while they are being uploaded and alert them that they are being uploaded?
  2. Yes, you need to upload multiple files