目录
前言
一. 文章背景
二. 项目结构
三. 核心代码解析
1. 页面结构
2. 属性介绍
3. 必要参数
4. 函数逻辑
四. 相关样式布局
五. 关键功能解释
六. 注意事项
七. 本文总结
前言
在这篇博客中,我们将深入探讨如何使用 Vue 和 el-upload 构建一个图片上传与管理功能。我们将创建一个上传图片、预览图片、下载图片和删除图片的完整功能,并通过一系列的 Vue 组件和方法来实现这些功能。在此过程中,我们还将处理文件上传的限制与管理,并实现界面的过渡动画效果。
一. 文章背景
本文旨在为用户提供一个图片上传识别的前端界面,允许用户上传图片,并进行智能识别。为提升用户体验,我们实现了图片的上传、预览、下载和删除功能,并根据不同操作展示不同的 UI 界面效果。
二. 项目结构
我们将页面结构分为以下几个部分:
- 页面标题:显示“智能 识别”。
- 左侧内容区域:主要包含图片上传区域,当没有准备上传的图片时,显示默认图片。
- 右侧内容区域:用于显示智能识别的结果(如待填充区域)。
- 图片预览:提供预览上传的图片功能。
- 文件上传与管理:通过 Element UI 的上传组件来处理文件上传,支持文件删除、预览和下载。
三. 核心代码解析
1. 页面结构
<template>
<div class="homeIndex_test">
<!-- 页面标题 -->
<header class="homeIndex_test_header">XX识别</header>
<!-- 主内容区域 -->
<div class="test_Con">
<!-- 左侧内容区域,带有过渡动画 -->
<transition name="slide_left">
<article class="testCon_left">
<!-- 图片展示区域,当没有准备上传图片时显示默认图片 -->
<div class="default_imgBox" v-if="!isUploadReady">
<div class="img_box">
<img src="@/assets/test1/photo1.png" alt="" />
</div>
</div>
<!-- 上传组件 -->
<el-upload class="upload_box" :action="uploadImg_url" :headers="headers" :auto-upload="true" name="files"
multiple :limit="limitNum" list-type="picture-card" v-model:file-list="fileList"
:on-change="handleChange">
<div class="aperate_btnBox">
<!-- 上传按钮 -->
<el-button class="upload_btn" slot="trigger" size="small" type="primary"
:disabled="this.upBtnDisable">
上传图片
<i class="el-icon-upload el-icon--right"></i>
</el-button>
<!-- 开始识别按钮,当图片上传准备好时显示 -->
<el-button v-if="isUploadReady" class="begin_btn" size="small" type="primary"
@click.stop="choseBeginSb">
开始识别
<i class="el-icon-refresh-left"></i>
</el-button>
</div>
<!-- 上传文件的操作项 -->
<div slot="file" slot-scope="{ file }">
<img class="el-upload-list__item-thumbnail" :src="file.url" alt="" />
<span class="el-upload-list__item-actions">
<!-- 预览图片操作 -->
<span class="el-upload-list__item-preview" @click="handlePictureCardPreview(file)">
<i class="el-icon-zoom-in"></i>
</span>
<!-- 下载图片操作 -->
<span class="el-upload-list__item-download" @click="handleDownload(file)">
<i class="el-icon-download"></i>
</span>
<!-- 删除图片操作 -->
<span class="el-upload-list__item-delete" @click="handleRemove(file)">
<i class="el-icon-delete"></i>
</span>
</span>
</div>
</el-upload>
<!-- 图片预览对话框 -->
<el-dialog :visible.sync="dialogVisible">
<img width="100%" :src="dialogImageUrl" alt="" />
</el-dialog>
</article>
</transition>
<!-- 右侧内容区域,带有过渡动画 -->
<transition name="slide_right">
<section v-if="showRightSection" class="testCon_right">
<!-- 识别结果区域 -->
</section>
</transition>
</div>
</div>
</template>
2. 属性介绍
:action="uploadImg_url" <!-- 必填:上传的服务器地址 -->
:headers="headers" <!-- 可选:设置上传请求头部信息 -->
:auto-upload="true" <!-- 必填:选择文件后是否自动上传 -->
name="files" <!-- 必填:上传接口接收文件参数的名字 -->
multiple <!-- 可选:允许一次选择多个文件 -->
:limit="limitNum" <!-- 可选:限制最大上传文件数量 -->
list-type="picture-card" <!-- 可选:文件列表展示类型,此处为图片卡片模式 -->
v-model:file-list="fileList" <!-- 必填:双向绑定文件列表到数据属性,跟踪已选文件 -->
:on-change="handleChange" <!-- 可选:当文件状态改变时触发的方法 -->
3. 必要参数
// 组件参数
// 上传图片的目标URL
uploadImg_url: process.env.VUE_APP_BASE_API + "/test/uploads",
// 自定义上传请求的头部信息,通常用于传递认证令牌等。
headers: {
Authorization: 'Bearer your-token-here'
},
// 双向绑定的文件列表,用于存储用户选择的文件信息。
fileList: [],
// 文件上传的最大数量限制。
limitNum: 3 // 示例:限制最多上传3个文件
// 其它参数
dialogImageUrl: '', // 对话框中显示的图片 URL
dialogVisible: false, // 控制图片预览对话框的显示状态
upBtnDisable: false, // 控制上传按钮是否禁用
isUploadReady: false, // 控制“开始识别”按钮的显示状态
showRightSection: false, // 控制右侧部分的显示状态
4. 函数逻辑
// 开始识别操作
choseBeginSb() {
this.showRightSection = true; // 显示右侧识别结果区域
},
// 上传文件变化处理函数,选择图片后触发
handleChange(file, fileList) {
this.fileList = fileList;
this.isUploadReady = fileList.length > 0;
// 限制上传文件的数量为3张
if (fileList.length >= 3) {
this.upBtnDisable = true;
this.$message({
message: '您已达到最大上传数量, 3张图片, 请删除后重新上传',
type: 'warning',
offset: 400,
showClose: true, // 是否显示关闭按钮
});
} else {
this.upBtnDisable = false;
}
},
// 图片预览函数
handlePictureCardPreview(file) {
this.dialogImageUrl = file.url;
this.dialogVisible = true;
},
// 下载图片函数
handleDownload(file) {
const link = document.createElement('a');
link.href = file.url;
link.download = file.name;
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
},
// 删除图片函数
handleRemove(file) {
const index = this.fileList.findIndex(f => f.uid === file.uid);
if (index !== -1) {
this.fileList.splice(index, 1);
}
this.isUploadReady = this.fileList.length > 0;
if (this.fileList.length < 3) {
this.upBtnDisable = false;
}
},
四. 相关样式布局
// CSS
::v-deep .testCon_right {
background-image:
linear-gradient(90deg,
rgba(255, 255, 255, 0.5),
rgba(192, 192, 192, 0.479),
rgba(255, 255, 255, 0.5));
background-size: 40px 100%;
background-repeat: no-repeat;
background-position: left -40px top 0;
animation: shine .8s ease infinite;
}
// 定义动画
@keyframes shine {
to {
background-position: right -40px top 0;
}
}
.el-upload-list__item-thumbnail {
position: relative;
/* 确保操作图标定位相对于图片 */
}
.el-upload-list__item-actions {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
/* 图标居中 */
z-index: 10;
opacity: 0;
transition: opacity 0.3s ease;
}
.el-upload-list__item-thumbnail:hover .el-upload-list__item-actions {
opacity: 1;
/* 鼠标悬停时显示操作图标 */
}
.el-upload-list__item-preview,
.el-upload-list__item-download,
.el-upload-list__item-delete {
margin: 0 5px;
cursor: pointer;
}
.el-upload-list__item-preview i,
.el-upload-list__item-download i,
.el-upload-list__item-delete i {
font-size: 16px;
/* 设置图标大小 */
}
.el-upload-list__item-delete i {
color: #f56c6c;
/* 删除图标颜色 */
}
.el-upload-list__item-preview i {
color: #409eff;
/* 放大图标颜色 */
}
.el-upload-list__item-download i {
color: #67c23a;
/* 下载图标颜色 */
}
// 隐藏上传按钮的边框
::v-deep .el-upload--picture-card {
border: none;
width: 100%;
height: 100px;
.aperate_btnBox {
width: 100%;
height: 100%;
display: flex;
justify-content: space-evenly;
align-items: center;
}
button {
height: 40px;
}
i {
// height: auto;
font-size: 20px;
}
}
// 上传图片的布局
::v-deep .el-upload-list {
width: 100%;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
&>li {
width: 220px;
height: 220px;
}
}
// 主页面布局
.homeIndex_test {
width: 100%;
height: calc(100vh - 84px);
// border: 1px solid red;
.homeIndex_test_header {
width: 100%;
height: 60px;
font-size: 22px;
font-weight: bolder;
// font-family: "楷体";
display: flex;
justify-content: center;
align-items: center;
border-bottom: 1px solid #46a6ff;
}
.test_Con {
width: 100%;
height: calc(100% - 60px);
box-sizing: border-box;
padding: 15px;
// border: 1px solid red;
display: flex;
justify-content: space-evenly;
align-items: center;
overflow: auto;
.testCon_left {
width: 49%;
height: 100%;
// box-shadow: 0px 0px 6px red;
border-radius: 6px;
.default_imgBox {
display: flex;
justify-content: center;
align-items: center;
.img_box {
width: 150px;
height: 150px;
border-radius: 50%;
background-color: #409eff;
display: flex;
justify-content: center;
align-items: center;
img {
width: 100px;
height: 100px;
}
}
}
.upload_box {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: center;
.upload_btn {
.el-icon-upload:before {
color: white;
font-size: 16px;
}
}
.begin_btn {
.el-icon-refresh-left:before {
color: white;
font-size: 16px;
}
}
}
}
.testCon_right {
width: 49%;
height: 100%;
// border: 1px solid red;
border-radius: 6px;
position: relative;
.parse_test {
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
font-size: 22px;
display: flex;
justify-content: center;
align-items: center;
font-family: "楷体";
}
.parse_btn {
position: absolute;
right: 2%;
bottom: 2%;
}
}
}
}
五. 关键功能解释
文件上传: 使用 Element UI 提供的
el-upload
组件处理图片的上传。v-model:file-list="fileList"
用于双向绑定文件列表,当文件上传时,我们通过handleChange
方法进行处理,检查上传的文件数量限制(最多上传三张图片)。上传按钮禁用: 当上传的图片数量超过 3 张时,上传按钮被禁用,并通过
this.upBtnDisable = true;
显示警告信息。用户需要删除一些图片才能继续上传。图片预览: 用户可以点击上传列表中的预览按钮查看图片详情,图片将通过
el-dialog
显示在弹窗中。图片下载和删除: 用户可以点击删除按钮移除文件,删除时会更新文件列表,并且控制上传按钮是否禁用。
过渡动画: 使用 Vue 的
transition
标签为左右两个区域的切换添加动画效果,使页面更具交互性。
六. 注意事项
- 文件上传数量限制:在实际应用中,我们可能需要根据实际需求调整上传文件的数量限制,例如支持多文件上传或限制文件大小。
- 性能优化:由于我们使用的是图片上传功能,因此需要处理大文件的上传,建议进行文件压缩或在服务器端进行文件大小校验。
- UI 交互:确保用户在上传图片时能够清晰地了解上传状态和错误信息,可以在合适的地方添加进度条或提示框。
七. 本文总结
本文介绍了如何使用 Vue 和 Element UI 实现一个图片上传与管理功能。通过本教程,您应该能够掌握如何使用 el-upload
组件实现文件上传、删除、预览、下载等基本功能,并且结合 Vue 的过渡动画增强用户体验。
八. 更多操作
早期关于上传的博客,请看