当前位置: 首页 > news >正文

网站建设石家庄快优最佳搜索引擎

网站建设石家庄快优,最佳搜索引擎,深圳外贸网站建设公司,微信里的小程序游戏怎么删除Vue 3 文件上传组件实现详解 在实际的前端开发中,文件上传是一个常见的需求,尤其是在需要处理文档、图片或其他类型文件的应用中。Vue 3 结合 Element Plus UI 组件库为我们提供了一个简单且灵活的文件上传解决方案。在这篇文章中,我们将详细…

Vue 3 文件上传组件实现详解

在实际的前端开发中,文件上传是一个常见的需求,尤其是在需要处理文档、图片或其他类型文件的应用中。Vue 3 结合 Element Plus UI 组件库为我们提供了一个简单且灵活的文件上传解决方案。在这篇文章中,我们将详细介绍一个文件上传组件的实现过程,并解释每一部分的逻辑和功能。

项目背景

假设我们正在开发一个表单功能,用户可以在表单中上传附件。这个附件可以是多种格式(如 doc, pdf, jpg 等),同时我们希望对上传的文件数量和大小进行限制。为了提高用户体验,我们还需要实现文件的删除功能和实时的上传提示信息。

需求分析
  • 文件类型和大小限制:允许用户上传特定类型和大小的文件。
  • 上传进度管理:能够在上传过程中显示状态信息。
  • 文件删除功能:支持上传文件的删除。
  • 实时提示:上传前后提供相应的提示信息(如格式不正确、大小超限等)。
组件实现

我们利用 el-upload 组件来实现文件上传功能。el-upload 是 Element Plus 提供的一个文件上传组件,它集成了文件上传、进度条、错误处理等常见功能。

1. 模板部分(<template>

<template><div class="upload-file"><el-uploadmultiple  <!-- 支持多文件上传 -->:action="uploadFileUrl"  <!-- 上传请求的地址 -->:before-upload="handleBeforeUpload"  <!-- 上传前的文件校验 -->:file-list="fileList"  <!-- 当前上传的文件列表 -->:limit="limit"  <!-- 上传文件数量限制 -->:on-error="handleUploadError"  <!-- 上传失败的回调 -->:on-exceed="handleExceed"  <!-- 超出文件数量限制的回调 -->:on-success="handleUploadSuccess"  <!-- 上传成功的回调 -->:show-file-list="false"  <!-- 不显示默认的文件列表 -->:headers="headers"  <!-- 上传请求的头部 -->class="upload-file-uploader"ref="fileUpload"><!-- 上传按钮 --><el-button type="primary" size="mini" icon="Upload" plain>上传附件</el-button></el-upload><!-- 上传提示 --><div class="el-upload__tip" v-if="showTip">请上传<template v-if="fileSize"> 大小不超过 <b style="color: #f56c6c">{{ fileSize }}MB</b> </template><template v-if="fileType"> 格式为 <b style="color: #f56c6c">{{ fileType.join("/") }}</b> </template>的文件</div><!-- 文件列表展示 --><transition-group class="upload-file-list el-upload-list el-upload-list--text" name="el-fade-in-linear" tag="ul"><li :key="file.uid" class="filelistcont" v-for="(file, index) in fileList"><div class="filelistcont-name"><span class="el-icon-document"> {{ getFileName(file.name) }} </span></div><div class="ele-upload-list__item-content-action"><el-link :underline="false" @click="handleDelete(index)" type="danger">删除</el-link></div></li></transition-group></div>
</template>
2. 脚本部分(<script setup>
<script setup>
import { getToken } from "@/utils/auth";// 接收外部传入的属性
const props = defineProps({modelValue: [String, Object, Array],  // 绑定的文件值,支持字符串、数组或对象limit: { type: Number, default: 5 },  // 限制上传的文件数量fileSize: { type: Number, default: 5 },  // 限制单个文件的大小(单位:MB)fileType: { type: Array, default: () => ["doc", "xls", "ppt", "txt", "pdf"] },  // 允许的文件类型isShowTip: { type: Boolean, default: true }  // 是否显示上传提示
});// 获取当前上下文中的代理对象,便于调用全局方法
const { proxy } = getCurrentInstance();
const emit = defineEmits();  // 定义组件的自定义事件
const number = ref(0);  // 记录上传的文件数量
const uploadList = ref([]);  // 上传成功的文件列表
const baseUrl = import.meta.env.VITE_APP_BASE_API;  // 基础 URL,接口地址
const uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + "/upload");  // 上传文件的接口
const headers = ref({ Authorization: "Bearer " + getToken() });  // 请求头,带上认证 token
const fileList = ref([]);  // 当前选择的文件列表
const showTip = computed(() => props.isShowTip && (props.fileType || props.fileSize));  // 控制是否显示上传提示信息// 监听 props.modelValue 的变化,并同步更新文件列表
watch(() => props.modelValue, val => {if (val) {let temp = 1;// 将传入的文件值转换为数组格式const list = Array.isArray(val) ? val : props.modelValue.split(',');// 将文件数组转换为对象数组,包含文件的名称和 URL 等信息fileList.value = list.map(item => {if (typeof item === "string") {item = { name: item, url: item };}item.uid = item.uid || new Date().getTime() + temp++;  // 为每个文件生成唯一的 uidreturn item;});} else {fileList.value = [];  // 清空文件列表}
}, { deep: true, immediate: true });// 上传前进行文件的类型和大小校验
function handleBeforeUpload(file) {// 校验文件类型if (props.fileType.length) {const fileName = file.name.split('.');const fileExt = fileName[fileName.length - 1];  // 获取文件扩展名const isTypeOk = props.fileType.indexOf(fileExt) >= 0;if (!isTypeOk) {proxy.$modal.msgError(`文件格式不正确, 请上传${props.fileType.join("/")}格式文件!`);return false;  // 阻止上传}}// 校验文件大小if (props.fileSize) {const isLt = file.size / 1024 / 1024 < props.fileSize;  // 判断文件大小是否小于限制值if (!isLt) {proxy.$modal.msgError(`上传文件大小不能超过 ${props.fileSize} MB!`);return false;  // 阻止上传}}proxy.$modal.loading("正在上传文件,请稍候...");  // 显示上传中的提示number.value++;  // 增加上传文件数量return true;  // 允许上传
}// 处理文件数量超出限制时的操作
function handleExceed() {proxy.$modal.msgError(`上传文件数量不能超过 ${props.limit} 个!`);
}// 处理上传失败的情况
function handleUploadError(err) {proxy.$modal.msgError("上传文件失败");
}// 处理上传成功的回调
function handleUploadSuccess(res, file) {if (res.url) {uploadList.value.push({ name: '/profile/' + res.path + res.filename, url: res.url });  // 保存文件的 URL 和路径uploadedSuccessfully();  // 上传成功后的处理} else {number.value--;  // 上传失败,减去上传计数proxy.$modal.closeLoading();  // 关闭加载提示proxy.$modal.msgError(res.msg);  // 显示错误信息proxy.$refs.fileUpload.handleRemove(file);  // 移除上传失败的文件uploadedSuccessfully();  // 上传失败后的处理}
}// 处理文件删除
function handleDelete(index) {fileList.value.splice(index, 1);  // 从文件列表中移除选中的文件emit("update:modelValue", listToString(fileList.value));  // 更新父组件的文件列表
}// 上传成功后,处理文件列表和状态的更新
function uploadedSuccessfully() {if (number.value > 0 && uploadList.value.length === number.value) {// 合并上传成功的文件与原始文件列表,并更新 fileListfileList.value = fileList.value.filter(f => f.url !== undefined).concat(uploadList.value);uploadList.value = [];  // 清空上传列表number.value = 0;  // 重置上传计数emit("update:modelValue", listToString(fileList.value));  // 更新父组件的文件列表proxy.$modal.closeLoading();  // 关闭加载提示}
}
// 获取文件名,避免 URL 显示
function getFileName(name) {if (name.lastIndexOf("/") > -1) {return name.slice(name.lastIndexOf("/") + 1);  // 获取文件名(去掉路径部分)} else {return name;  // 如果没有路径,直接返回文件名}
}// 将文件列表转换为字符串(以逗号分隔)
function listToString(list, separator) {let strs = "";separator = separator || ",";  // 默认使用逗号分隔for (let i in list) {if (list[i].url) {strs += list[i].url + separator;  // 拼接 URL 字符串}}return strs !== '' ? strs.substr(0, strs.length - 1) : '';  // 去掉最后一个分隔符
}
</script>

3. 样式部分

<style scoped>
.upload-file {position: relative;
}
.upload-file .filelistcont {display: flex;align-items: center;justify-content: space-between;padding: 8px 12px;border: 1px solid #dcdfe6;margin-bottom: 8px;border-radius: 4px;
}
.upload-file .filelistcont-name {overflow: hidden;text-overflow: ellipsis;white-space: nowrap;
}
.el-upload__tip {margin-top: 12px;font-size: 12px;color: #999;
}
</style>

总结

通过结合 Vue 3 的响应式特性和 Element Plus 的 el-upload 组件,我们实现了一个功能完善的文件上传组件。这个组件不仅支持文件的上传、校验和删除,还提供了上传进度提示和错误处理。通过自定义的事件机制,我们可以将文件列表从子组件传递到父组件,确保数据的同步和状态管理。

在实际开发中,根据不同的需求,组件的功能可以进一步扩展,比如支持上传进度条、拖拽上传、批量处理等。希望通过这篇文章,你能深入理解 Vue 3 文件上传组件的实现,并能够在自己的项目中灵活应用。

http://www.yidumall.com/news/10634.html

相关文章:

  • 网站建设以及运营方面网络优化的内容包括哪些
  • 保险做的好的网站有哪些内容网站维护的主要内容
  • 开封做网站公司汉狮品牌营销策略四种类型
  • 网站建设与管理 ppt模板b2b平台
  • 揭阳网站制作专业谷歌seo是什么意思
  • 湖北网站建设多少钱中国十大搜索引擎排名最新
  • 网站模板怎么上传网络营销平台名词解释
  • 自己创免费网站国外seo比较好的博客网站
  • 宜昌市建设信息网站文案代写在哪里接单子
  • 网站哪家做的好河南网站seo推广
  • web网站开发语言嘉定区整站seo十大排名
  • 江苏网站建设电话百度百科怎么创建自己
  • 百度网做网站吗网络推广方法技巧
  • 通辽做网站通过seo来赚钱seo排名优化推广
  • 旅游网站建设合同外贸怎么建立自己的网站
  • 商业网站教程今日热搜第一名
  • 怎样做b2b网站网站收录免费咨询
  • 怎么做监测网站的浏览量制作网站需要多少费用
  • 现在那个网站做视频最赚钱百度网站介绍
  • 中建八局一公司待遇怎么样seo关键词优化报价价格
  • 做外贸网站的都有哪些类型的公司优化营商环境 助推高质量发展
  • 做外贸雨伞到什么网站怎样在百度上推广
  • 网站收录后才可以做排名吗河南企业站seo
  • 阿里巴巴国际站的前台网址是今日重大事件
  • 网站制作网站建网络销售怎么做才能有业务
  • 如何修改网站后台国内永久免费云服务器
  • 微信上发的链接网站怎么做的营销型企业网站诊断
  • 可信网站logo优化手机流畅度的软件
  • 武汉做网站icp产品宣传推广方案
  • 商丘网站建设推广公司桔子seo查询