在上一篇中,我们单纯的实现了Ctrl + V实现从粘贴版中获取图片信息,但是点击上传的时候会有个bug,就是点击文件上传的时候,会出现一个bug,这篇,我们将在上一篇的基础上进行完善,并支持从粘贴版中获取文件内容,同时对上传文件的大小进行判断,且支持PDF,Docx,Doc,PPT等文件进行上传。
实现步骤
-
安装 Element UI
确保你已经安装了 Element UI 并在项目中正确配置。
-
创建拖拽上传组件
假设你已经有一个基本的拖拽上传组件,我们将在其基础上添加 Ctrl + V 功能。
-
监听粘贴事件
我们需要在页面中监听 paste 事件,当用户按下 Ctrl + V 时,捕获粘贴板中的文件数据。
-
处理粘贴事件
在捕获到文件数据后,将其转换为 File 对象,并调用上传方法。
实现代码
html
<template>
<div>
<el-upload
drag
action="https://jsonplaceholder.typicode.com/posts/"
:on-preview="handlePreview"
:on-remove="handleRemove"
:before-upload="beforeUpload"
:on-success="handleSuccess"
multiple
ref="upload"
:file-list="fileList"
>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">支持上传多种文件类型</div>
</el-upload>
<!-- 显示上传后的文件 -->
<div v-for="(file, index) in fileList" :key="index" class="uploaded-file">
<div v-if="isImage(file.name)">
<img :src="file.url" alt="Uploaded Image" class="uploaded-image" />
<el-button type="text" @click="removeFile(index)">移除</el-button>
</div>
<div v-else>
<span>{{ file.name }}</span>
<el-button type="text" @click="removeFile(index)">移除</el-button>
</div>
</div>
</div>
</template>
CSS
css
<style scoped>
.uploaded-file {
margin-top: 10px;
display: flex;
align-items: center;
}
.uploaded-image {
max-width: 100px;
max-height: 100px;
margin-right: 10px;
}
</style>
JavaScript
js
<script>
import { Upload } from 'element-ui';
export default {
name: 'DragUpload',
data() {
return {
fileList: []
};
},
methods: {
handlePaste(event) {
const items = event.clipboardData.items;
for (let i = 0; i < items.length; i++) {
const allowedTypes = [
'image/jpeg', 'image/png',
'application/pdf',
'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // DOC, DOCX
'application/vnd.ms-powerpoint', 'application/vnd.openxmlformats-officedocument.presentationml.presentation' // PPT, PPTX
];
if (allowedTypes.includes(items[i].type)) {
const file = items[i].getAsFile();
this.handleFile(file);
break;
}
}
},
handleFile(file) {
const reader = new FileReader();
reader.onload = (e) => {
this.fileList.push({
name: file.name,
url: e.target.result
});
};
reader.readAsDataURL(file);
this.$refs.upload.handleStart(file);
this.$refs.upload.submit();
},
handlePreview(file) {
console.log('Preview:', file);
},
handleRemove(file, fileList) {
this.fileList = fileList;
},
beforeUpload(file) {
const allowedTypes = [
'image/jpeg', 'image/png',
'application/pdf',
'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', // DOC, DOCX
'application/vnd.ms-powerpoint', 'application/vnd.openxmlformats-officedocument.presentationml.presentation' // PPT, PPTX
];
const isAllowedType = allowedTypes.includes(file.type);
const isLt500K = file.size / 1024 < 500;
if (!isAllowedType) {
this.$message.error('只能上传 JPG/PNG/PDF/DOC/DOCX/PPT/PPTX 格式的文件!');
}
if (!isLt500K) {
this.$message.error('文件大小不能超过 500KB!');
}
return isAllowedType && isLt500K;
},
handleSuccess(response, file, fileList) {
// 更新 fileList
this.fileList = fileList.map(f => ({
name: f.name,
url: f.url || f.response.url // 假设服务器返回的响应中有 url 字段
}));
},
removeFile(index) {
this.fileList.splice(index, 1);
},
isImage(fileName) {
return fileName.toLowerCase().endsWith('.jpg') || fileName.toLowerCase().endsWith('.png');
}
},
mounted() {
document.addEventListener('paste', this.handlePaste);
},
beforeDestroy() {
document.removeEventListener('paste', this.handlePaste);
}
};
</script>
说明
- HTML部分:
- 使用
el-upload
组件创建一个拖拽上传区域。 - 使用
v-for
循环遍历 fileList 数组,显示每个上传的文件。 - 如果文件是图片,显示图片预览和移除按钮。
- 如果文件不是图片,显示文件名和移除按钮。
- CSS部分:
- 添加了一些基本样式来美化上传后的文件显示。
- JavaScript部分:
fileList
数据属性用于存储上传的文件列表。handlePaste
方法:捕获粘贴事件,检查粘贴板中的数据是否为支持的文件类型(图片、PDF、DOC、DOCX、PPT、PPTX),如果是,则调用 handleFile 方法。handleFile
方法:读取文件内容并将其添加到 fileList 中,同时触发上传。handleRemove
方法:更新 fileList 以反映文件的移除。beforeUpload
方法:检查文件类型和大小,确保只上传允许的文件类型。handleSuccess
方法:处理文件上传成功后的响应,并更新 fileList。removeFile
方法:从 fileList 中移除指定索引的文件。isImage
方法:判断文件名是否为图片文件。