自定义拖拽上传文件

嗨,不知道你是否和我一样呢? 想过element-ui的文件拖拽上传是怎么做的? 是怎么监听实时上传进度的呢? 今天就来搞一下,low不low不管,先搞为敬.哈哈

1.关于拖住的API

1.1在拖动目标上触发事件 (源元素):

  1. ondragstart - 用户开始拖动元素时触发
  2. ondrag - 元素正在拖动时触发
  3. ondragend - 用户完成元素拖动后触发

1.2释放目标时触发的事件:

  1. ondragenter - 当被鼠标拖动的对象进入其容器范围内时触发此事件
  2. ondragover - 当某被拖动的对象在另一对象容器范围内拖动时触发此事件
  3. ondragleave - 当被鼠标拖动的对象离开其容器范围内时触发此事件
  4. ondrop - 在一个拖动过程中,释放鼠标键时触发此事件

在拖动元素时,每隔 350 毫秒会触发 ondrag 事件

1.3 实现元素拖拽

<pdraggable="true" >设置属性后既可以拖动</p>

那么知道了基础API,那就让我们来做一个拖拽上传的实例吧:

上上个效果图吧,没图没动力嘛,哈哈

话不多说,先上代码为敬(代码每一行都有注释)

<template>

<divclass="index">

<divclass="index-box">

<!-- 本地上传进度 -->

<divclass="index-progress">

<divclass="index-progress-name">本地上传进度:</div>

<divclass="index-progress-number">

<el-progress:percentage="scale":status="scaleName ? scaleName : null "></el-progress>

</div>

</div>

<!-- 拖拽区域 -->

<divclass="index-drag"

ref="updataDrag"

@dragover="updataDragover"

@dragenter="updataDragenter"

@dragleave="updataDragleave"

@drop="updateDrop">

<divclass="index-drag-iconBox">

<spanclass="el-icon-upload"></span>

</div>

<divclass="index-drag-message">

<spanclass="index-drag-message-titles">将文件拖动到此处,或</span>

<labelfor="file"class="index-drag-message-label">

<inputclass="index-drag-message-input"type="file"id="file"name="file" @change="manualChange" />

<spanclass="index-drag-message-manual">点击上传</span>

</label>

</div>

</div>

<!-- 本地上传进度 -->

<divclass="index-progress">

<divclass="index-progress-name">服务器上传进度:</div>

<divclass="index-progress-number">

<el-progress:percentage="network":status="networkName ? networkName : null "></el-progress>

</div>

</div>

</div>

</div>

</template>

<script>

import axios from'axios'

exportdefault {

data(){

return {

scale: 0 ,// 本地上传进度

scaleName: null,

network: 0 , // 网络上传

networkName: null

}

},

methods:{

// 当被拖动的对象在另一对象容器范围内拖动时触发此事件

updataDragover(ev){

// 注意 这里跟关键哈

ev.preventDefault()

},

// 被鼠标拖动的对象进入其容器范围内时触发此事件

updataDragenter(){

this.scaleName = null

// 当被拖拽元素进入 目标区域时, 目标边框变为 蓝色

this.$refs.updataDrag.style.borderColor = '#4B87FF'

this.$refs.updataDrag.style.background = '#F7F7F8'

},

// 当被鼠标拖动的对象离开其容器范围内时触发此事件

updataDragleave(){

// 当被拖拽元素离开 目标区域时, 目标边框变为 灰色

this.$refs.updataDrag.style.borderColor = '#A3A3A3'

this.$refs.updataDrag.style.background = '#ffffff'

},

// 在一个拖动过程中,释放鼠标键时触发此事件

updateDrop(ev){

let oFile = ev.dataTransfer.files[0];

this.readerFile(oFile)

// 这里阻止默认事件 为阻止浏览器自动打开拖拽文件

ev.preventDefault()

},

// 手动上传文件

manualChange(ev){

let oFile = ev.target.files[0]

this.readerFile(oFile)

},

// 读取文件

readerFile(oFile){

let This = this

var reader = new FileReader();

//读取成功

reader.onload = function(ev){

// 以下文件类型判断并不准确,仅入门级,准确的判断 应直接判断 Buffer(这里不再赘述)

// 转 Base64

let txt = ev.target.result;

// 分号位置

let semicolonIndex = txt.indexOf(';')

// 冒号位置

let colonIndex = txt.indexOf(':')

// 文本类型

let txtType = txt.slice(colonIndex + 1,semicolonIndex)

// 详细类型

let types = ''

let format = ''

// 这里 不知道 在Mac下是不是('')呢? 哈哈

let txtTypeArr = txtType.split('/')

if(txtTypeArr[0] === 'image'){

console.log('图片: 类型为' + txtTypeArr[1])

// Base64 转 图片文件

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('视频: 类型为' + txtTypeArr[1])

let params = new FormData()

params.append('file',oFile) //

This.submitUpdata(params)

}

};

reader.onloadstart = function(){

console.log('读取开始');

This.scaleName = null

};

reader.onloadend = function(){

console.log('读取结束');

This.scaleName = 'success'

};

reader.onabort = function(){

console.log('中断');

This.scaleName = 'exception'

};

reader.onerror = function(){

console.log('读取失败');

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 转 图片

baseImage(dataurl, filename) {

let arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],

bstr = atob(arr[1]), n = bstr.length, u8arr = newUint8Array(n);

while(n--){

u8arr[n] = bstr.charCodeAt(n);

}

returnnew File([u8arr], filename, {type:mime});

},

// 上传

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){

// 上传处理进度事件

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){

// 为下载处理进度事件

}

})

.then(res => {

// 具体状态码 自行判断 这里用别人的 状态码是 201 哈哈 真实提交不成功哈

if(res.status >= 200 && res.status <= 206){

This.networkName = 'success'

}

if(res.status >= 400){

This.networkName = 'exception'

}

})

}

}

}

</script>

<stylescoped>

.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>

拓展

  1. 是否还应该判断 当文件正在上传时,是否阻止其他文件的拓转进入,并给出正在上传的提醒呢?
  2. 是的需要多文件的拓转上传呢

以上是 自定义拖拽上传文件 的全部内容, 来源链接: utcz.com/a/26483.html

回到顶部