更新记录

1.0.2(2025-03-28) 下载此版本

修复微信小程序端上传的一些问题。

1.0.1(2025-03-27) 下载此版本

完善信息

1.0.0(2025-03-27) 下载此版本

任意格式大文件分片续传上传(非原生)功能

查看更多

平台兼容性

Vue2 Vue3
App 快应用 微信小程序 支付宝小程序 百度小程序 字节小程序 QQ小程序
HBuilderX 3.95 app-vue app-nvue × × × × ×
钉钉小程序 快手小程序 飞书小程序 京东小程序 鸿蒙元服务
× × × × ×
H5-Safari Android Browser 微信浏览器(Android) QQ浏览器(Android) Chrome IE Edge Firefox PC-Safari
× × ×

breakpoint-upload

下载须知!!!

为更好的鞭策我持续维护和更新插件的动力,如果亲觉得好用,可以支持下小弟噢~

本插件适用 App [ Android、iOS ]、 微信小程序、H5 应用

支持所有格式文件选择和上传

插件使用注意事项

控件的 height、width 应与 slot 自定义内容宽高度保持一致。

nvue 窗口只能使用固定模式 position=absolute 。

show() 当 DOM 重排后在 this.$nextTick 内调用 show(),控件定位会更加准确。

hide() APP 端 webview 层级比 view 高,如不希望触发点击时,应调用 hide 隐藏控件,反之调用 show。

APP 端请优先联调 Android,上传成功后再运行 iOS 端。

若 iOS 端跨域服务端同学实在配置不好,可把 hybrid 下 html 目录放到服务器去,同源则不存在跨域问题。

小程序端因 hybrid 不能使用本地 HTML,所以插件提供的是从微信消息列表拉取文件并选择,请知悉。

关于很多问 file 对象打印出来是{}的问题(由于file对象是二进制流),你可以打印 file.name 和 file.size。

本插件实现大文件拆分成小片文件一一上传,支持批量上传,支持所有文件格式,后端代码请自行实现.参考地址(https://www.cnblogs.com/songsu/p/17838356.html)

本插件上传参数与返回数据可能与你的接口不一致,后面可自行修改处理。(H5、微信小程序请修改BreakpointUploadFile.js,APP请修改hybrid->html->uploadFile.html)


上传报 status:0 问题排查

App 如果上传报 status: 0,调试方法:关闭 manifest.json>h5 的代理(若有配置代理),并运行项目至 Chrome 浏览器,按 F12 查看接口详细报错信息(重点:是 Chrome,不是 HX 内置浏览器)

Android 端不存在跨域问题,如上传报 status: 0 时

1、如果能进入接口,但收不到任何参数,检查是否在 option>header 里传入了 Content-Type 属性(默认不需要传,会自动匹配,若接口要求必须传则需要与接口匹配)

2、如果未能进入接口,检查 nginx 网关配置,不清楚可加群查看群相册资料。

iOS 端若出现 status:0,排除上面两个问题后只会是跨域问题

1、后端处理允许上传接口跨域。(前端无需修改)

2、若后端不放开跨域,可将 hybrid>html 文件夹放入与接口同源的服务器,同源访问则不存在跨域问题。(可加群查看群相册资料)


使用说明

属性 是否必填 值类型 默认值 说明
permission String 组件内查看 需要校验的系统权限集合
isPermissionInToast Boolean true 未授权时是否显示内置 Toast 提示权限 permission[].message,建议传 true
isPermissionInModal Boolean true 用户拒绝授权时是否显示内置弹框引导用户开启权限
width String 100% 容器宽度(App 必填且与 slot 内容宽度一致)
height String 80rpx 容器高度(App 必填且与 slot 内容高度一致)
debug Boolean false 打印调试日志
option Object - 文件上传接口相关参数
partsize Number 5242880 分片大小,单位字节 (5MB)
instantly Boolean true instantly=true:选择文件后自动上传
distinct Boolean false 是否去重同名文件(提示:不去重复时前端展示同名文件名称后面+(N),后端接收到的 file.name 还是为原名)
count Number 10 文件选择上限(个)
size Number 10 文件大小上限(M)
multiple Boolean true 是否允许多选
wxFileType String all 微信小程序文件选择器格式限制(all=从所有文件选择,video=只能选择视频文件,image=只能选择图片文件,file=可以选择除了图片和视频之外的其它的文件)
accept String - 文件选择器 input file 格式限制(有效值自行百度查 accept)
formats String - 限制允许上传的格式,空串=不限制,默认为空,多个格式以逗号隔开,例如 png,jpg,pdf
childId String breakpointUpload 自定义组件 id,在回调函数第二个参数返回(若页面有多个组件可用于区分是哪个组件回调)
position String static 控件的定位模式(static=控件随页面滚动;absolute=控件在页面中绝对定位,不随窗口内容滚动)
top,left,right,bottom [Number,String] 0 设置控件绝对位置,position=absolute 时有效
@changeFile Function Map 选择文件后触发,返回所有已选择文件 Map 集合
@progress Function Object 上传中持续触发,返回正在上传的文件对象,可通过 set 更新至页面显示上传进度
@uploadEnd Function Object 上传结束回调,返回当前上传的文件对象,type 等于 success(上传成功)返回 responseText 属性(服务端返回数据)
@permissionBefore Function Object 某项权限未授权时触发回调,返回{permission,message},仅 isPermissionInToast 传 false 时生效
@permissionFail Function Object 用户拒绝授权时触发回调,返回{permission,message,result}

新增 uni.$emit 事件监听

方法名 说明
$upload-show 调用当前页面所有上传组件的 show()
$upload-hide 调用当前页面所有上传组件的 hide()

使用示例

this.$nextTick(() => {
    // 更新当前页所有上传组件在页面中的位置
    uni.$emit('$upload-show', {});
});

vue:

<breakpoint-upload
    ref="breakpointUpload1"
    isSystemNavigationBar
    :count="limit"
    :size="100 * 1024"
    width="180rpx"
    height="180rpx"
    :debug="false"
    :instantly="true"
    :option="uploadOpt"
    @changeFile="getFileSelect"
    @progress=""
    @uploadEnd="onuploadEnd"
>
    <view class="ctm-ref-file-add-btn">
        <image src="@/static/image/camera.png" mode="widthFix"></image>
    </view>
</breakpoint-upload>

<view class="padding">

    <view>已选择文件列表:</view>
    <view class="mc-list">
        <template v-if="fileList.length > 0">
            <view class="mc-li flex-wrap box-align" v-for="item in fileList" :key="item.id">
                <view class="mc-doc-icon flex-wrap box-align box-pack">
                    <image v-if="item.isImage" :src="BASE_URL + item.serverUrl" mode="widthFix"></image>
                    <image
                        v-else
                        :src="
                            item?.reponse?.data?.suffix.includes('doc')
                                ? icon1
                                : item?.reponse?.data?.suffix.includes('xls')
                                ? icon2
                                : item?.reponse?.data?.suffix.includes('pdf')
                                ? icon3
                                : item?.reponse?.data?.suffix.includes('mp4')
                                ? icon5
                                : item?.reponse?.data?.suffix.includes('mp3')
                                ? icon6
                                : icon4
                        "
                        mode="widthFix"
                    ></image>
                </view>
                <view class="flex-con">
                    <view class="mc-doc-title">{{ item.name }}</view>
                    <view class="mc-doc-tip">
                        <view v-if="item.status == 'success'">
                            <uni-tag text="上传成功" type="success" :circle="true" size="small"></uni-tag>
                        </view>
                        <view v-else-if="item.status == 'error'">
                            <uni-tag text="上传失败" type="error" :circle="true" size="small"></uni-tag>
                        </view>
                        <view class="flex-wrap box-align" v-else>
                            <view class="flex-con"><ctm-progress :percentage="item.progress"></ctm-progress></view>
                            <text v-if="item.curChunk">({{ item.curChunk ? item.curChunk : '' }} / {{ item.chunks }})</text>
                        </view>
                    </view>
                </view>
                <uni-icons class="ctm-close" type="close" size="24" @click="deleteFile(item)"></uni-icons>
            </view>
        </template>
    </view>
</view>

  • 函数说明
export default {
    data() {
        return {
            // 上传接口参数
            option: {
                // 上传服务器地址,需要替换为你的接口地址
                url: 'http://test/document/upload', // 该地址非真实路径,需替换为你项目自己的接口地址
                // 上传附件的key
                name: 'file',
                // 根据你接口需求自定义请求头,默认不要写content-type,让浏览器自适配
                header: {
                    // 示例参数可删除
                    Token: 'xxxxxxxx',
                },
                // 根据你接口需求自定义body参数
                formData: {},
            },
            // 选择文件后是否立即自动上传,true=选择后立即上传
            instantly: true,
            // 选择文件是否去重
            distinct: false,
            // 必传宽高且宽高应与slot宽高保持一致
            width: '180rpx',
            height: '180rpx',
            // 限制允许上传的格式,空串=不限制,默认为空
            formats: '',
            // 文件上传大小限制
            size: 30,
            // 文件数量限制
            count: 2,
            // 是否多选
            multiple: true,
            // 文件回显列表
            files: new Map(),
            // 是否打印日志
            debug: true,
        };
    },
    onReady() {

    },
    methods: {

};

温馨提示

  • 文件上传
  1. APP 端请优先联调 Android,上传成功后再运行 iOS 端,如 iOS 返回 status=0 则需要后端开启允许跨域;
  2. header 的 Content-Type 类型需要与服务端要求一致,否则收不到附件(服务端若没有明文规定则不写,使用默认匹配)
  3. 服务端不清楚怎么配置跨域可 491979303咨询,具体百度~

隐私、权限声明

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

需要开启相机、相册相关权限

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

插件不采集任何数据

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

许可协议

MIT协议

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