手写React点击拖拽导入组件

1,333 阅读2分钟

这是我参与8月更文挑战的第2天,活动详情查看:8月更文挑战

实现功能

  • 组件基于React-Typescript项目开发
  • 是关于导入Excel文件格式的具体实现
  • 支持点击以及拖拽导入
  • 导入后解析文档数据为json格式,点击确定后,通过接口提交json数据到后台
  • 组件预览(UI参考elementUI拖拽上传组件) import.png

实现

原理

思路

  • 单击上传:
    • 点击拖拽区域时,手动触发inputclick事件,通过display:none隐藏真实的input元素
    // basic-upload.tsx
    
    // 手动触发 input 的 click 事件
      const inputEl = useRef<HTMLInputElement>(null)
      const handleClick = () => {
        if (inputEl.current) {
          inputEl.current.click()
        }
      }
    return (
        <>
          <UploadDragger onClick={handleClick}>
            <div className='drag-tip'>
              <CloudUploadIcon />
              <div>将文件拖到此处,或点击上传</div>
            </div>
          </UploadDragger>
          <div className={classes.uploadTip}>
            只能上传符合模板的文件,点击<span className={classes.downloadTemp} onClick={downloadTemp}>下载模板</span>
          </div>
          <input ref={inputEl} className={classes.inputInvisible} type='file' onChange={handleChange} accept={'png'}></input>
        </>
      )
    
    • 监听inputchange事件,解析文件
    // basic-upload.tsx
    
    // 上传解析文件
      const handleChange = (evt: ChangeEvent<HTMLInputElement>) => {
        let files = evt.target.files // File对象
        const reader = new FileReader() // FileReader对象实例
        reader.onload = function fileReadCompleted() {
          let result = analyseBrokerFile(reader) // analyseBrokerFile方法 解析文件为json数据
          ...
        }
        if (files) reader.readAsText(files[0], 'gbk') // gbk编码方式异步读取文件
      }
    
  • 拖拽上传并解析
    • 监听onDrop事件,e.dataTransfer.files获取文件信息,同上方式解析成json文件
    const UploadDragger = (props:PropType) => {
      const { onClick } = props
      const classes = draggerStyles()
    
      const onDrop = (e: React.DragEvent) => {
        e.preventDefault()
        let files= e.dataTransfer.files
        const reader = new FileReader()
        reader.onload = function fileReadCompleted() {
          let data = analyseBrokerFile(reader)
          ...
        }
        if (files) reader.readAsText(files[0], 'gbk')
      }
      return (
        <div onClick={onClick} className={classes.dragger} onDrop={onDrop} onDragOver={onDragOver} onDragLeave={onDragLeave}>
          {props.children}
        </div>
      )
    }
    export default UploadDragger
    
  • 解析方法:analyseBrokerFile方法自行定义,根据不同项目,不同Excel文件内容解析成不同的json数据。思路主要就是在文件读取完成时,内容在reader.result中,通过正则、遍历等方式过滤处理数据

总结

  • 拖拽实现方式跟单击上传方式一样,只是监听事件不同
  • 此外还可增加一些其它功能,如上传进度、多文件上传、文件格式筛选判断、文件大大小限制等等

参考