更新记录

1.0.6(2025-03-30)

修复一处逻辑错误

1.0.5(2025-03-29)

修复全选功能的部分bug

1.0.4(2025-03-29)

修复文件过多导致的组件卡顿问题,每页显示最多500个文件(夹);新增功能,可以全选/全不选文件

查看更多

平台兼容性

Vue2 Vue3
×
App 快应用 微信小程序 支付宝小程序 百度小程序 字节小程序 QQ小程序
HBuilderX 4.31,Android:11.0,iOS:不支持,HarmonyNext:不支持 × × × × × ×
钉钉小程序 快手小程序 飞书小程序 京东小程序 鸿蒙元服务
× × × × ×
H5-Safari Android Browser 微信浏览器(Android) QQ浏览器(Android) Chrome IE Edge Firefox PC-Safari
× × × × × × × × ×

使用前注意

本插件由于使用android.permission.MANAGE_EXTERNAL_STORAGE权限,因此须确保在Android 11及以上版本运行。
本插件需要打包自定义调试基座,打包前确保权限已在AndroidManifest.xml申请,示例如下:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="io.dcloud.uniappx">
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

</manifest>

插件还有任何其他问题,欢迎和作者联系。

使用方法

引入插件

<cfit-filepicker path="/sdcard/DCIM" :multiple="true"></cfit-filepicker>

其中参数path必须以/sdcard开头;不写这个参数默认操作目录为/sdcard/Download
参数multipletrue则文件可多选;否则为单选。
文件选择完成后最终返回的是一个路径数组。

相关事件

import { onInputChange, showFilepick,uploadFile,fileReader } from "@/uni_modules/cfit-filepicker"
onInputChange(callback(e):string) //当有文件被选中后触发,从这里可以接收指定文件的绝对路径的数组,例如["/sdcard/enc.key","/sdcard/.temp","/sdcard/screenshot.png","/sdcard/.archivetemp.zip"]
showFilepick() //引入插件后默认不打开,使用此函数开启文件选择器
uploadFile(uploadurl:string,filepath:string,method:string,data:string,header:string,callback(res,e):string) //filepath为单个文件路径,method为HTTP请求方法(POST、PUT等),data和header为传入的其他HTTP数据,须满足JSON格式;res为返回信息,e为错误信息
fileReader(path:string,method:string,callback(e):string) // path为单个路径,method有base64、hex、raw三种方式,e为回传结果。其中base64返回的为dataURL风格。

参考代码

请注意,以下代码请使用uniapp x运行。代码内的上传链接、dataheader等参数运行时须自行修改。

<template>
    <view class="container">
        <view class="card">
            <text class="title">文件上传</text>
            <text class="subtitle">选择文件并上传到服务器</text>

            <view class="file-picker">
                <button class="select-btn" @click="show">
                    <text class="btn-text">选择文件</text>
                </button>
                <cfit-filepicker path="/sdcard/DCIM" :multiple="true"></cfit-filepicker>

                <view class="file-info" v-if="nowinput">
                    <text class="file-name">{{nowinput.split('/').pop()}}</text>
                    <text class="file-selected">已选择文件</text>
                </view>
                <view class="file-info" v-else>
                    <text class="file-hint">未选择任何文件</text>
                </view>
            </view>

            <button class="upload-btn" :disabled="nowinput==''" @click="upload">
                <text class="btn-text">上传文件</text>
            </button>
        </view>
    </view>
</template>

<script>
    import { onInputChange, showFilepick, uploadFile, fileReader } from "@/uni_modules/cfit-filepicker"
    export default {
        data() {
            return {
                uploadurl: "http://192.168.43.136:7869/upload",
                nowinput: "",
                method: "PUT",
                data: JSON.stringify({ userId: "123", description: "test file" }) as string,
                header: JSON.stringify({ Authorization: "Bearer CF1T70k3n5053" }) as string,
                inputarray: [""]
            }
        },
        onLoad() {
            // 注册文件选择变化回调,当用户选择文件后会触发
            onInputChange((e) => {
                console.log(e);
                const res = e as string;
                this.inputarray = JSON.parse(res) as UTSArray<String>;
                this.nowinput = this.inputarray[0]; // 将选择的文件路径保存到nowinput
            })
        },
        methods: {
            show() {
                // 打开文件选择器
                showFilepick();
            },
            upload() {
                if (this.inputarray.length > 0) {
                    /**
                     * 这部分为读取文件内容,上传文件不需要
                     * 使用fileReader可以读取文件内容,支持base64、hex、raw三种格式
                    **/
                    // fileReader(this.inputarray[0],"base64",(e)=>{
                    //  console.log(e)
                    // });
                    for (var i = 0; i < this.inputarray.length; i++) {
                        console.log("上传中. . .")
                        uni.showLoading({
                            title: `上传${this.inputarray[i]}中. . .`
                        })
                        // 调用uploadFile上传文件
                        // 参数依次为:上传URL、文件路径、HTTP方法、附加数据、请求头、回调函数
                        uploadFile(
                            this.uploadurl,
                            this.inputarray[i],
                            this.method,
                            this.data,
                            this.header,
                            (result, error) => {
                                uni.hideLoading();
                                if (error != "") {
                                    console.log(`Upload failed: ${error}`)
                                    uni.showToast({
                                        title: `上传失败:${error}`,
                                        position: "bottom"
                                    })
                                } else {
                                    uni.showToast({
                                        title: `上传成功`,
                                        position: "bottom"
                                    })
                                    console.log(`Upload success: ${result.trim()}`)
                                }
                            }
                        )
                    }
                }
            }
        }
    }
</script>

<style>
    .container {
        display: flex;
        justify-content: center;
        align-items: center;
        background-color: #f5f7fa;
        padding: 20px;
    }

    .card {
        width: 100%;
        max-width: 500px;
        background-color: #ffffff;
        border-radius: 12px;
        padding: 24px;
        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
    }

    .title {
        font-size: 24px;
        font-weight: 700;
        color: #333;
        text-align: center;
        margin-bottom: 8px;
    }

    .subtitle {
        font-size: 14px;
        color: #666;
        text-align: center;
        margin-bottom: 24px;
    }

    .file-picker {
        margin-bottom: 24px;
        border: 1px dashed #d9d9d9;
        border-radius: 8px;
        padding: 20px;
    }

    .select-btn {
        background-color: #409eff;
        color: white;
        border-radius: 6px;
        padding: 1px 5px;
        margin-bottom: 16px;
    }

    .btn-text {
        font-size: 16px;
        font-weight: 700;
        color: #f5f7fa;
    }

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

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

    .file-selected {
        font-size: 12px;
        color: #0077ff;
    }

    .file-hint {
        font-size: 14px;
        color: #999;
    }

    .upload-btn {
        background-color: #0066ff;
        color: white;
        border-radius: 6px;
        padding: 7px 5px;
    }
</style>

隐私、权限声明

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

<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

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

插件不采集任何数据

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

暂无用户评论。

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问