一、react-dropzone
官方定义: Simple HTML5-compliant drag'n'drop zone for files built with React.js.
理解: 一个为react量身定制,基于H5 API:drop && drag
可以实现拖拽上传文件的npm插件包
是的,以后再也不用自己苦苦地封装drop和drag了, react-dropzone
使用非常简单,只需要调用一个事件.
当然这个包是针对于react的(直接作为组件使用),如果需要非组件的,直接npm官网搜索dropzone即可.
简单看一个效果图
二、用法
第一步当然是给项目添加插件包
//安装
npm install -D react-dropzone
//项目引入
import ReactDropzone from 'react-dropzone'
//项目使用
<ReactDroppzone
onDrop = {xxx}
...
/>
我们先来全面认识一下它
基础功能: onDrop事件
function onDrop(acceptedFiles, rejectedFiles) {
//识别成功的文件
console.log(acceptedFiles)
//识别失败的文件
console.log(rejectedFiles)
}
默认是可以接收任何文件,即使文件类型无法识别;
做一个测试,我同时上传.jpg .doc 文件夹 .html .pdf
,然后打印一下上传成功后的信息
我们可以看到只有文件夹
类型不能识别.另外还有一些其他属性
lastModified
: 最后一次修改文件的时间lastModifiedDate
: 最后一次修改文件的日期preview
: 预览,后面具体介绍一下
限制文件类型
只需要在组件里添加accept
属性即可
<ReactDropZone
accept="pdf/*"
onDrop = {this.handleDrop}
/>
如果我上传非pdf类文件,会输出到rejectFiles
,我们打印一下
上传文件预览
//提取file里面preview值即可
{
fileArr.length > 0 && fileArr.map( (item, index) => (
<div key={index} className="previewDiv">
<h3>预览</h3>
<img alt="Preview" src={item.preview} className="previewImg"/>
</div>))
}
样式相关属性
Default State(dropzone原始状态): className
&& style
Drag is Active(拖拽到盒子上但未放开): activeClassName
&& activeStyle
Dropped Files are Accepted(拖拽后,文件能被识别): acceptClassName
&& acceptStyle
Dropped Files are Rejected(拖拽后,文件不能被识别):rejectClassName
&& rejectStyle
Dropzone is Disabled(功能被禁止时): disabledClassName
&& disabledStyle
最后一条是在disabled="true"
时生效
当设置了这个属性,在DOM里可以看到变成:aria-disabled="true"
字面上意思应该是无障碍交流,当时我实际上用的时候,是自动打开这个文件.(比如拖拽了一个图片后,会自动用浏览器打开)
结合React
import React,{ Fragment } from 'react'
import './style.css'
import ReactDropZone from 'react-dropzone'
export default class DropzoneComp extends React.Component{
constructor(props){
super(props)
this.state = {
fileArr: []
}
this.handleDrop = this.handleDrop.bind(this);
}
handleDrop(acceptFile, rejectFile){
let { fileArr } = this.state;
console.log('acceptFile ======>', acceptFile)
console.log('rejectFile ======>', rejectFile)
if(rejectFile.length){
alert('不支持该格式')
return;
}
acceptFile.map( item => {
fileArr.push(item)
})
this.setState({
fileArr,
})
}
render(){
const { fileArr } = this.state;
return(
<div className="dropzone">
<div className="upload initUpload">
<p>
原上传文件方式
</p>
<input type="file"/>
</div>
<div className="upload dropzoneUpload">
<p>
dropzone上传方式
</p>
<ReactDropZone
className="dropZoneStyles"
activeClassName="dragStyles"
acceptClassName="addDropZoneStyles"
accept="image/*"
onDrop = {this.handleDrop}
>
<span>+</span>
</ReactDropZone>
{
fileArr.length ? fileArr.map( (item, index) => (
<p >{item.name}</p>
)) : <p>未选择任何文件</p>
}
</div>
{
fileArr.length > 0 && fileArr.map( (item, index) => (
<div key={index} className="previewDiv">
<h3>预览</h3>
<img alt="Preview" src={item.preview} className="previewImg"/>
</div>))
}
</div>
)
}
}