更新记录

1.4.0(2026-06-22)

修复 iOS 编译模块错误

1.3.0(2026-04-08)

支持 iOS 26

1.2.3(2025-08-06)

修复Android选择文件执行多次回调问题

查看更多

平台兼容性

uni-app(5.0)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android iOS 鸿蒙
√ √ - - √ √ 5.0 12 -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - - -

uni-app x(4.75)

Chrome Safari Android iOS 鸿蒙 微信小程序
- - 5.0 12 - -

rl-select-files - 文件选择

一个简单易用的文件选择器插件,支持多种文件类型选择、多选、进度显示等功能。

✨ 特性

  • 支持多种文件类型(图片、视频、音频等)
  • 支持单选和多选
  • 支持文件选择进度显示
  • 支持自定义文件类型
  • 支持大文件处理
  • 文件自动缓存管理

🎯 兼容性

  • iOS 14.0+
  • Android 10+
  • HormanyOS 观望中

📦 安装

将插件导入到项目的 uni_modules 目录下。

📖 API 说明

SelectFilesType 文件类型

type SelectFilesType = 'any' | 'media' | 'image' | 'video' | 'audio' | 'custom'

SelectFilesOptions 请求参数

参数 类型 必填 说明
type SelectFilesType 是 文件类型: 'any'/'media'/'image'/'video'/'audio'/'custom'
allowedExtensions string 否 自定义文件扩展名(type为custom时有效),如:'pdf,doc,docx'
allowMultiple boolean 否 是否允许多选
proceed function 否 处理进度回调
success function 否 选择成功回调
fail function 否 选择失败回调
cancel function 否 取消选择回调

SelectFilesProgress 进度数据

字段 类型 说明
currentFileIndex number 当前处理的文件索引
totalFiles number 总文件数
currentFileName string 当前文件名
progress number 当前文件进度(0-1)
totalProgress number 总体进度(0-1)

SelectFilesResult 返回数据 - 成功

字段 类型 说明
name string 文件名
size number 文件大小(字节)
formattedSize string 格式化后的文件大小(如:1.5MB)
cachePath string 文件缓存路径

SelectFilesFail 返回数据 - 失败

字段 类型 说明
errMsg string 错误信息

selectFiles 请求文件选择

字段 类型 说明
options SelectFilesOptions 请求信息

🔨 使用方法

基础用法

import { selectFiles } from '@/uni_modules/rl-select-files'

// 选择视频文件
selectFiles({
    type: 'video',             // 文件类型
    allowedExtensions: '',     // 允许的扩展名(type为custom时使用)
    allowMultiple: true,       // 是否允许多选
    // 处理进度回调
    proceed: (progress) => {
        console.log(
            `处理文件: ${progress.currentFileName} ` +
            `(${progress.currentFileIndex}/${progress.totalFiles}) - ` +
            `${Math.floor(progress.totalProgress * 100)}%`
        )
    },
    // 选择成功回调
    success: (files) => {
        console.log('选择的文件:', files)
    },
    // 选择失败回调
    fail: (error) => {
        console.error('选择失败:', error.errMsg)
    },
    // 用户取消选择回调
    cancel: () => {
        console.log('用户取消选择')
    }
})

完整实例

<template>
    <view>
        <view class="button-container">
            <button @click="filePickTest">选择文件</button>
            <button @click="filePickClear">清除缓存</button>
        </view>

        <!-- 进度显示 -->
        <view v-if="progress" class="progress-container">
            <text class="progress-text">{{progress}}</text>
        </view>

        <!-- 文件列表 - 修改这部分 -->
        <scroll-view vertical>
            <view class="file-list">
                <text class="list-title" v-if="pickFiles.length > 0">已选择的文件:</text>
                <view v-for="(file, index) in pickFiles" :key="index" class="file-item">
                    <view class="file-info">
                        <text class="file-name">{{file.name}}</text>
                        <text class="file-size">大小:{{file.formattedSize}}</text>
                        <text class="file-path" v-if="file.cachePath">缓存路径:{{file.cachePath}}</text>
                    </view>
                </view>
            </view>
        </scroll-view>
    </view>
</template>

<script>
    import {
        SelectFilesOptions,
        SelectFilesFail,
        SelectFilesResult,
        selectFiles,
        clearCache,
    } from '@/uni_modules/rl-select-files'

    export default {
        data() {
            return {
                title: 'Hello',
                progress: '',
                pickFiles: [] as SelectFilesResult[]
            }
        },
        methods: {
            filePickTest() {
                this.progress = "" 
                this.pickFiles.splice(0, this.pickFiles.length)
                let options: SelectFilesOptions = {
                    type: 'video',
                    allowedExtensions: '',
                    allowMultiple: true,
                    proceed: (progress) => {
                        this.progress = `处理文件: ${progress.currentFileName} ` +
                            `(${progress.currentFileIndex}/${progress.totalFiles}) - ` +
                            `${Math.floor(progress.totalProgress * 100)}%`
                    },
                    success: (result) => {
                        if(result != null) {
                            let files = JSON.parseArray<SelectFilesResult>(result)
                            let totalSize = 0
                            if(files != null) {

                                files?.map(file => {
                                    totalSize += file.size
                                })
                                let totalSizeFormat = this.formatSize(totalSize)
                                this.progress = `文件处理完毕` +
                                    ` - 共${files?.length}个文件` +
                                    ` - 共${totalSizeFormat}`

                                this.pickFiles.push(...files)
                            }
                        }
                    },
                    fail: (error) => {
                        console.error('选择失败:', error.errMsg)
                        uni.showToast({
                            title: error.errMsg,
                            icon: 'none'
                        })
                    },
                    cancel: () => {
                        console.log('用户取消选择')
                    }
                }
                selectFiles(options)
            },

            filePickClear() {
                clearCache()
                this.progress = ""
                this.pickFiles.splice(0, this.pickFiles.length)
                uni.showToast({
                    title: '缓存已清理',
                    icon: 'success'
                })
            },

            formatSize(size : number) : string {
                const units = ['B', 'KB', 'MB', 'GB', 'TB']
                let index = 0
                let fileSize = size
                while (fileSize >= 1024 && index < units.length - 1) {
                    fileSize /= 1024
                    index++
                }
                return `${fileSize.toFixed(1)} ${units[index]}`
            }
        },

        beforeDestroy() {
            clearCache()
        }
    }
</script>

<style>
    .button-container {
        padding: 0 20px;
        margin-bottom: 20px;
    }

    .button-container button {
        margin-bottom: 10px;
    }

    .progress-container {
        padding: 10px 20px;
        background-color: #f8f8f8;
        margin: 0 20px 20px 20px;
        border-radius: 5px;
    }

    .progress-text {
        font-size: 14px;
        color: #666;
    }

    /* 修改文件列表样式 */
    .file-list {
        padding: 0 20px;
        flex: 1;
    }

    .list-title {
        font-size: 16px;
        font-weight: bold;
        margin-bottom: 10px;
        color: #333;
    }

    .file-item {
        background-color: #f8f8f8;
        padding: 15px;
        margin-bottom: 10px;
        border-radius: 8px;
    }

    .file-info {
        display: flex;
        flex-direction: column;
    }

    .file-name {
        font-size: 16px;
        font-weight: bold;
        color: #333;
        margin-bottom: 5px;
    }

    .file-size {
        font-size: 14px;
        color: #666;
        margin-bottom: 5px;
    }

    .file-path {
        font-size: 12px;
        color: #999;
        word-break: break-all;
    }
</style>

⚠️ 注意事项

  1. 选择的文件会自动缓存到本地,提高文件可操作性
  2. 建议在适当的时候调用 clearCache() 清理缓存
  3. 大文件处理时会显示进度
  4. iOS 14.0+ 设备才能使用此插件
  5. Android 10+ 设备才能使用此插件
  6. 在组件销毁时记得调用 clearCache() 清理缓存
  7. 大文件(>10MB)会自动使用分块处理以提高性能
  8. 文件选择完成后会返回缓存路径,可以直接使用
  9. 支持安全的文件访问机制
  10. 选择取消时会触发 cancel 回调
  11. 支持可达1G以上大文件

🤝 贡献/咨询

欢迎提交 issue 和 PR,一起完善这个插件。 扣***:838332280

📝 开发文档

UTS 语法 UTS API插件 UTS 组件插件 Hello UTS

隐私、权限声明

1. 本插件需要申请的系统权限列表:

Android: READ_EXTERNAL_STORAGE :读取存储权限 WRITE_EXTERNAL_STORAGE:写入存储权限 IOS: NSPhotoLibraryUsageDescription:是否允许App访问您的相册 NSPhotoLibraryAddUsageDescription:是否允许App访问您的相册 NSAppleMusicUsageDescription:是否允许App访问您的媒体资料库

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

无

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

暂无用户评论。