思路是通过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 = ""
}
码字不易,有错误欢迎指正