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

如何封装一个上传文件组件

        #今天用el-upload感到很多不方便,遂决定自己封装一个。注:本文不提供表面的按钮样式和文件上传成功后的样式,需要自己创建。本文仅介绍逻辑函数#

1,准备几个表面用来指引上传的元素

2,创造统一的隐藏文件上传输入框,监听文件改变函数来监听文件的上传

    <input 
        type="file"
         ref="fileInput" 
        class="hidden" 
        @change="handleFileUpload" 
        :accept="currentFileType" 
/>

你放在哪里都行,反正要隐藏起来,用来调用点击事件

3,准备文件上传的Ref和上传成功的文件的数组,记得ref要绑定上面的输入框

  1. 创造ref绑定输入框,用于读取上传到文件相关信息
  2. 创建上传数组用于存放上传文件组合,有文件名字,文件类型,文件路径(图片和视频才有),文件大小
// 文件上传ref
const fileInput = ref<HTMLInputElement | null>(null)
// 上传的文件列表
const uploadedFiles = reactive<{
    name: string;
    type: 'file' | 'image' | 'video';
    url?: string;
    size: string;
}[]>([]);

4,点击表面的上传按钮时,调用隐藏的上传输入框的click事件

        事件要绑定在上面的隐藏输入框

const handleFile = () => {
    fileInput.value?.click()
}

5, 处理文件上传函数

  1.  如果文件数组为空则返回
  2. 检查文件大小,如果为video视频文件并且文件大小大于100MB同样返回
  3. 确定文件类型,同样使用startsWith函数
  4. 添加到文件上传列表中,包含名字,类型,创造的url(视频或图片才有),大小(格式化函数返回)
  5. 最后清除文件上传框
const handleFileUpload = (event: Event) => {
    const input = event.target as HTMLInputElement;
    if (!input.files || input.files.length === 0) 
    {
        alert('您没有上传文件')
        return
    };
    
    Array.from(input.files).forEach(file => {
        // 检查视频文件大小
        if( file.type.startsWith('video/') && file.size > 100 * 1024 * 1024){
            alert(`视频文件${file.name}太大, 请限制在100MB以内`);
            return
        }

        // 确定文件类型
        let fileType: 'file' | 'image' | 'video' = 'file';
        if (file.type.startsWith('image/')) {
            fileType = 'image';
        } else if (file.type.startsWith('video/')) {
            fileType = 'video';
        }

        // 添加到上传列表
        uploadedFiles.push({
            name: file.name,
            type: fileType,
            url: fileType !== 'file' ? URL.createObjectURL(file) : undefined,
            size: formatFileSize(file.size)
        });
        
        alert(`已经添加:${file.name}`)
    })
    input.value = '';
}

6,格式化函数,用来计算文件大小,传入函数为文件的大小,单位B

  1. 定义大小四个单位
  2. 循环计算哪个大小单位,每次除以1024
  3. 最后返回得到的size是除完后的结果,toFixed保留一位小数
const formatFileSize = (bytes: number): string => {
    const units = ['B', 'KB', 'MB', 'GB']
    let size = bytes
    let unitIndex = 0
    while (size >= 1024 && unitIndex < units.length -1){
        size /= 1024
        unitIndex++;
    }
    return `${size.toFixed(1)} ${units[unitIndex]}`
}

7, 删除文件函数,需要绑定在删除元素上

比如绑定在文件删除按钮,点击时触发,传入文件数组的对应索引

  1. 如果对应文件存在URL路径,需要统一肢解路径,使用函数URL.revokeObjectURL(对应url字符串)
  2. splice根据索引删除对应元素
const removeFile = (index:number) =>{
    if (uploadedFiles[index].url)
        URL.revokeObjectURL(uploadedFiles[index].url)
    uploadedFiles.splice(index, 1)
    alert.warning('已删除文件')
}

8,清除函数,在组件销毁前调用

同第七条,在组件关闭前调用URL.revokeObjectURL函数解放url,防止永远无法复用

// 清理函数
const cleanupBlobUrls = () =>{
    uploadedFiles.forEach(file => {
        if (file.url)
        URL.revokeObjectURL(file.url)
    })
}
// 在组件销毁前调用
onBeforeUnmount(() => {
    cleanupBlobUrls()
})

9,最后在HTML中自由渲染函数即可 


  补充:

  • startWith函数:startsWith()用于确定此字符串是否以指定字符串的字符开头,并根据需要返回truefalse

  • 输入文件通过event.target.files去寻找,为上传文件组成的数组,有type,name,size等属性
  • URL.createObjectURL()接受文件(比如图片和视频),创建URL一个字符串,是一串指向传入文件的URL路径。
  • URL.revokeObjectURL()接受URL路径,释放URL和原本对应文件的链接

http://www.dtcms.com/a/98106.html

相关文章:

  • 小河:团队金牌精准计划
  • QML中使用Image显示图片和使用QQuickItem显示图片
  • 告别桌面杂乱与充电焦虑,移速165W百变桌面充电站首发体验
  • Day43 | 129. 求根节点到叶节点数字之和、1382. 将二叉搜索树变平衡、100. 相同的树
  • 循相似之迹:解锁协同过滤的核心推荐逻辑
  • OpenBMC:BmcWeb 生效路由4 将路由添加到Trie中
  • Spring Boot事务管理详解(附银行转账案例)
  • 如何缩短研发周期,降低研发成本?全星APQP软件为您提供解决方案
  • 【Goalng】第九弹-----文件操作、JSON处理
  • 杂草YOLO数据集分享
  • 【AI插件开发】Notepad++插件开发实践:从基础交互到ScintillaCall集成
  • 第十五章:Python的Pandas库详解及常见用法
  • 【云原生】docker 搭建单机PostgreSQL操作详解
  • Pod 网络与 CNI 的作用
  • 结构化分析方法 数据流图详解
  • 每日一题-力扣-2360. 图中的最长环 0329
  • Java 大视界 -- 基于 Java 的大数据分布式计算在基因测序数据分析中的性能优化(161)
  • 力扣刷题1049. 最后一块石头的重量 II
  • Swiss Dock:免费的在线分子对接工具(支持两种对接算法切换)
  • 信号与系统(郑君里)第一章-绪论 1-23 课后习题解答
  • 基于Java与Go的下一代DDoS防御体系构建实战
  • 图像数据增强教程:为目标检测任务准备数据
  • 基于RFID技术建筑物资材料智能管理解决方案
  • 迭代器与可迭代对象
  • 《汽车理论》第三章作业
  • 电脑ip地址每次开机会换吗?全面解析
  • 蓝桥杯 之 图论基础+并查集
  • 什么是openAPI
  • IDEA如何设置以新窗口打开新项目
  • 基于RK3588的YOLO多线程推理多级硬件加速引擎框架设计(项目总览和加速效果)