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):
- Ondragstart – Triggered when the user starts dragging elements
- Ondrag – Triggered while the element is dragging
- Ondragend – Triggered when the user finishes dragging the element
1.2 Events triggered when releasing the target:
- Ondragenter – This event is triggered when a mouse-dragged object enters its container scope
- Ondragover – This event is triggered when a dragged object is dragged within the scope of another object container
- Ondragleave – This event is triggered when an object dragged by the mouse leaves its container scope
- 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
- 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?
- Yes, you need to upload multiple files