手把手用vue生成一个支持拖拽的upload组件

117 阅读1分钟

思路是通过html5的表单进行上传,利用隐藏的input,实现点击上传,对于拖拽,是通过监听drag事件实现的

    <tempalte>
        <div class="upload-wrapper" 
            :class="{active: isDragEnter}" 
            @click="handleClick"
            @dragOver.prevent="handleDragOver"
            @dragLeave="handleDragLeave"
            @drag.prevent="handleDrop"
        >
            <div v-if="imgSrc" class="upload-res">
                <img :src="imgSrc" class="upload-img">
                <div class="upload-close" @click.stop="handleFileDelete"></div>
            </div>
            
            <div class="upload-reStart" v-if="imgSrc" @click="handleReStart"></div>
            <div v-else>
                <i class="upload-icon"></i>
                <p class="uplaod-tip">uplaod or drag an image here</p>
            </div>
            <input class="hidden" ref="input" type="file" :accept="accept" />
        </div>
    </template>
    
    props: {
        accept: String, // 'png,jpeg'
        fileUrl: String
    }
    
    data: {
        isDragEnter:false,
        imgSrc: '',
        file: ''
    }
    
    handleClick(){
        if(!this.imgSrc) {
            this.$refs.input.click()
        }
    }
    
    handleDragOver(){
        this.isDragEnter = true
    }
    
    handleDragLeave(){
        this.isDragEnter = false
    }
    

拖拽的核心实现

    handleDrop(e) {
        const {accept} = this;
        if(!accept) {
            const files = [].slice.call(e.dataTransfer.files)
            this.handleUpload(files) // 如果只需要一个文件就穿files[0]
        } else {
            const files = [].slice.call(e.datatTransfer.files).filter(file => {
                const {type, name} = file
                const extension = name.indexOf(".") > -1 ? `${name.split(".").pop()}` : ""
                const baseType = type.replace(/\/.*$/, "")
                return accept.split(",").map(type => type.trim()).filter(type => type).some(acceptType =>{
                    if(/\..+$/.test(acceptedType)) {
                        return extention === acceptedType
                    }
                    
                    if(/\/\*$/.test(acceptType)) {
                        return baseType === acceptedType.replace(/\/\*$/, "")
                    }
                    
                    if(/^[^\/]+\/[^\/]+$/.test(acceptType)){
                        return type === acceptedType
                    }
                })
                this.handleUpload(files)
            })
        }
    }

缩略图实现

    handleUpload(file) {
        // 这里以一个举例子
        const simpleFile = file[0]
        const formData = new FormData()
        formData.append('file', file)
        
        // 文件上传接口
        
        // 这里是用url实现,也可以通过FileReader的readerAsDataUrl实现
        const src = URL.createObject(file)
        this.imageSrc=  src;
    }

删除

    handleUpload(){
        this.imgSrc = ""
        this.$refs.input.value = ""
    }

码字不易,有错误欢迎指正