Upload
组件类型:UxUploadComponentPublicInstance
支持图片视频,支持删除、排序功能,支持进度显示
平台兼容性
UniApp X
Android | iOS | web | 鸿蒙 Next | 小程序 |
---|---|---|---|---|
√ | √ | √ | x | √ |
UniApp Vue Nvue
Android | iOS | web | 鸿蒙 Next | 小程序 |
---|---|---|---|---|
x | x | √ | x | x |
Props
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
list | Array | 默认列表 | |
name | String | file | 文件对应的key,开发者在服务器端通过这个key可以获取到文件二进制内容 |
url | String | 上传地址 | |
header | UTSJSONObject | HTTP请求Header,header中不能设置Referer | |
formData | UTSJSONObject | HTTP请求中其他额外的formdata | |
timeout | Number | 120000 | 超时时间,单位ms |
retry | Number | 3 | 重试次数 |
successCode | Number | 200 | 上传成功状态码 |
mode | String | image | 模式 |
count | Number | 9 | 最大数量 |
sizeType | Array | ['original','compressed'] | original原图,compressed压缩图Web不支持 |
sourceType | Array | ['album','camera'] | album从相册选图,camera使用相机 |
extension | Array | 文件拓展名过滤仅Web支持 | |
align | String | left | 对齐方向 |
rows | Boolean | true | 多行 |
col | Number | 4 | 列数,rows=true时生效 |
gutter | Any | 间隔默认5) | |
width | Any | 65 | 文件宽,rows=false时生效 |
height | Any | 65 | 文件高,rows=false时生效 |
radius | Any | 8 | 圆角 |
background | String | 按钮背景色 | |
backgroundDark | String | 深色none-不显示,auto-自动适配深色模式,其他-颜色 | |
borderColor | String | 按钮边框色 | |
borderColorDark | String | 深色none-不显示,auto-自动适配深色模式,其他-颜色 | |
waitingText | String | 等待上传 | 等待上传文案 |
failText | String | 上传失败 | 等待失败文案 |
frontBtn | Boolean | false | 前置上传按钮 |
showDel | Boolean | true | 显示删除按钮 |
beforeDel | Function | 删除钩子 | |
beforeUpload | Function | 上传前钩子 | |
afterUpload | Function | 上传完成钩子 | |
autoUpload | Boolean | true | 自动上传 |
disabled | Boolean | false | 禁用 |
mode
值 | 说明 |
---|---|
image图片 | |
video视频 | |
media媒体 | |
file文件 |
align
值 | 说明 |
---|---|
left居左 | |
right居右 |
backgroundDark
值 | 说明 |
---|---|
none不显示 | |
auto自动适配深色模式 | |
color其他颜色 |
borderColorDark
值 | 说明 |
---|---|
none不显示 | |
auto自动适配深色模式 | |
color其他颜色 |
Events
事件名 | 说明 | 参数 |
---|---|---|
click | 点击时触发 | |
change | 值改变时触发 | |
error | 发生错误时触发 |
示例代码
html
<template>
<ux-page :stack="showDoc">
<ux-navbar :title="title" :bold="true">
<template v-slot:right>
<!-- #ifndef MP -->
<ux-button theme="text" icon="/static/tip.png" :icon-size="22" @click="onDoc()"></ux-button>
<!-- #endif -->
</template>
</ux-navbar>
<ux-scroll>
<ux-card direction="column" icon="flag-filled" title="上传" :bold="true">
<ux-text text="支持图片视频、支持宫格、单行滚动显示,支持手动提交上传"></ux-text>
</ux-card>
<ux-card direction="column" icon="arrowright" title="上传图片" :bold="true">
<ux-text text="支持宫格显示" :mb="15"></ux-text>
<ux-upload :list="files1" :after-upload="afterUpload" :before-del="beforeDel" :url="url" mode="image" @click="onPreview" @change="change1"></ux-upload>
</ux-card>
<ux-card direction="column" icon="arrowright" title="上传视频" :bold="true">
<ux-text text="支持配置视频缩略图显示" :mb="15"></ux-text>
<ux-upload :list="files2" :after-upload="afterUpload" :before-del="beforeDel" :url="url" mode="video" @click="onPreview" @change="change2"></ux-upload>
</ux-card>
<ux-card direction="column" icon="arrowright" title="上传媒体" :bold="true">
<ux-text text="支持上传按钮前置, 支持单行滚动显示" :mb="15"></ux-text>
<ux-upload :front-btn="true" :list="files3" :before-upload="beforeUpload" :after-upload="afterUpload" :before-del="beforeDel" :url="url" mode="media" :rows="false" @click="onPreview" @change="change3"></ux-upload>
</ux-card>
<ux-card direction="column" icon="arrowright" title="手动上传" :bold="true">
<ux-upload ref="uxUploadRef" :auto-upload="false" :front-btn="true" :list="files4" :after-upload="afterUpload" :before-del="beforeDel" :url="url" mode="image" @click="onPreview" @change="change4"></ux-upload>
<ux-button :mt="15" theme="primary" text="点击上传" @click="submit"></ux-button>
</ux-card>
<ux-card direction="column" icon="arrowright" title="表单数据" :bold="true">
<ux-text text="支持传入 header、formData" :mb="15"></ux-text>
<ux-upload :form-data="formData" :success-code="204" :list="files5" :before-del="beforeDel" :url="url2" mode="image" @click="onPreview" @change="change5"></ux-upload>
</ux-card>
<ux-card direction="column" icon="arrowright" title="上传文件" :bold="true">
<ux-text text="暂不支持上文件上传" :mb="15"></ux-text>
<ux-upload mode="file" @error="error"></ux-upload>
</ux-card>
<ux-placeholder :height="200">
<ux-row justify="center" align="center" style="height: 100%;">
<ux-text prefix-icon="soapbubble-filled" text="真的没有了~"></ux-text>
</ux-row>
</ux-placeholder>
</ux-scroll>
</ux-page>
</template>
<template>
<ux-page :stack="showDoc">
<ux-navbar :title="title" :bold="true">
<template v-slot:right>
<!-- #ifndef MP -->
<ux-button theme="text" icon="/static/tip.png" :icon-size="22" @click="onDoc()"></ux-button>
<!-- #endif -->
</template>
</ux-navbar>
<ux-scroll>
<ux-card direction="column" icon="flag-filled" title="上传" :bold="true">
<ux-text text="支持图片视频、支持宫格、单行滚动显示,支持手动提交上传"></ux-text>
</ux-card>
<ux-card direction="column" icon="arrowright" title="上传图片" :bold="true">
<ux-text text="支持宫格显示" :mb="15"></ux-text>
<ux-upload :list="files1" :after-upload="afterUpload" :before-del="beforeDel" :url="url" mode="image" @click="onPreview" @change="change1"></ux-upload>
</ux-card>
<ux-card direction="column" icon="arrowright" title="上传视频" :bold="true">
<ux-text text="支持配置视频缩略图显示" :mb="15"></ux-text>
<ux-upload :list="files2" :after-upload="afterUpload" :before-del="beforeDel" :url="url" mode="video" @click="onPreview" @change="change2"></ux-upload>
</ux-card>
<ux-card direction="column" icon="arrowright" title="上传媒体" :bold="true">
<ux-text text="支持上传按钮前置, 支持单行滚动显示" :mb="15"></ux-text>
<ux-upload :front-btn="true" :list="files3" :before-upload="beforeUpload" :after-upload="afterUpload" :before-del="beforeDel" :url="url" mode="media" :rows="false" @click="onPreview" @change="change3"></ux-upload>
</ux-card>
<ux-card direction="column" icon="arrowright" title="手动上传" :bold="true">
<ux-upload ref="uxUploadRef" :auto-upload="false" :front-btn="true" :list="files4" :after-upload="afterUpload" :before-del="beforeDel" :url="url" mode="image" @click="onPreview" @change="change4"></ux-upload>
<ux-button :mt="15" theme="primary" text="点击上传" @click="submit"></ux-button>
</ux-card>
<ux-card direction="column" icon="arrowright" title="表单数据" :bold="true">
<ux-text text="支持传入 header、formData" :mb="15"></ux-text>
<ux-upload :form-data="formData" :success-code="204" :list="files5" :before-del="beforeDel" :url="url2" mode="image" @click="onPreview" @change="change5"></ux-upload>
</ux-card>
<ux-card direction="column" icon="arrowright" title="上传文件" :bold="true">
<ux-text text="暂不支持上文件上传" :mb="15"></ux-text>
<ux-upload mode="file" @error="error"></ux-upload>
</ux-card>
<ux-placeholder :height="200">
<ux-row justify="center" align="center" style="height: 100%;">
<ux-text prefix-icon="soapbubble-filled" text="真的没有了~"></ux-text>
</ux-row>
</ux-placeholder>
</ux-scroll>
</ux-page>
</template>
ts
<script setup>
import * as plus from '@/uni_modules/ux-plus'
import { UxUploadFile } from '@/uni_modules/ux-frame';
const title = ref('')
const uxUploadRef = ref<UxUploadComponentPublicInstance | null>(null)
const url = 'https://test.api.fdproxy.cn/file/upload/add'
const url2 = 'http://jxqft.com:9000/shaokx'
const files1 = ref<UTSJSONObject[]>([{
id: '1',
url: 'http://gips0.baidu.com/it/u=1690853528,2506870245&fm=3028&app=3028&f=JPEG&fmt=auto?w=1024&h=1024'
},{
id: '2',
url: 'http://gips2.baidu.com/it/u=195724436,3554684702&fm=3028&app=3028&f=JPEG&fmt=auto?w=1280&h=960'
}] )
const files2 = ref<UTSJSONObject[]>([])
const files3 = ref<UTSJSONObject[]>([])
const files4 = ref<UTSJSONObject[]>([])
const files5 = ref<UTSJSONObject[]>([])
const formData = ref<UTSJSONObject>({
'bucket': "shaokx",
'key': "/newhouse/20240718102240.png",
'policy': "eyJjb25kaXRpb25zIjpbWyJlcSIsIiRidWNrZXQiLCJzaGFva3giXSxbImVxIiwiJGtleSIsIi9uZXdob3VzZS8yMDI0MDcxODEwMjI0MC5wbmciXSxbImVxIiwiJHgtYW16LW1ldGEtZGVzY3JpcHRpb24iLCLmlYjmnpzlm74iXSxbImVxIiwiJHgtYW16LWRhdGUiLCIyMDI0MDcxOFQwMjIyNDBaIl0sWyJlcSIsIiR4LWFtei1hbGdvcml0aG0iLCJBV1M0LUhNQUMtU0hBMjU2Il0sWyJlcSIsIiR4LWFtei1jcmVkZW50aWFsIiwiS3ZxMnZoU3VCODZTeU1RalBPTVkvMjAyNDA3MTgvdXMtZWFzdC0xL3MzL2F3czRfcmVxdWVzdCJdXSwiZXhwaXJhdGlvbiI6IjIwMjQtMDctMTlUMDI6MjI6MDAuMjIyWiJ9",
'x-amz-algorithm': "AWS4-HMAC-SHA256",
'x-amz-credential': "Kvq2vhSuB86SyMQjPOMY/20240718/us-east-1/s3/aws4_request",
'x-amz-date': "20240718T022240Z",
'x-amz-meta-description': "效果图",
'x-amz-signature': "650b89ad802c2aab3b05536b30c02b4ac5116454421e9662c0b4d1a69069f4c7"
})
function change1(files: UxUploadFile[]) {
console.log(files);
}
function change2(files: UxUploadFile[]) {
console.log(files);
}
function change3(files: UxUploadFile[]) {
console.log(files);
}
function change4(files: UxUploadFile[]) {
console.log(files);
}
function change5(files: UxUploadFile[]) {
console.log(files);
}
function error(err: string) {
uni.showToast({
title: err,
icon: 'none'
})
}
function beforeUpload(path: string): UTSJSONObject | null {
return null
}
function afterUpload(data: string):string {
uni.hideLoading()
let res = JSON.parseObject(data)
let d = res?.getJSON('data')
return d?.getString('url') ?? ''
}
async function beforeDel(index: number, file: UxUploadFile):Promise<boolean> {
return new Promise<boolean>((resolve) => {
uni.showModal({
content: '确定删除吗?',
success: (e) => {
if(e.confirm) {
resolve(true)
} else {
resolve(false)
}
}
})
})
}
function onPreview(index: number, files: UxUploadFile[]) {
let arr = files.filter((e):boolean => e.status == 'success').map((e): string => e.path)
uni.previewImage({
urls: arr,
current: index
})
// 视频未处理
}
function submit() {
uni.showLoading({
title: '上传中...',
})
uxUploadRef.value?.$callMethod('upload')
}
const showDoc = ref(false)
function onDoc() {
plus.openWeb({
title: '在线文档',
url: 'https://www.uxframe.cn/component/upload.html',
// blur: 1,
success: () => {
showDoc.value = true
},
complete: () => {
showDoc.value = false
}
})
}
onLoad((e) => {
title.value = e['title'] ?? ''
})
</script>
<script setup>
import * as plus from '@/uni_modules/ux-plus'
import { UxUploadFile } from '@/uni_modules/ux-frame';
const title = ref('')
const uxUploadRef = ref<UxUploadComponentPublicInstance | null>(null)
const url = 'https://test.api.fdproxy.cn/file/upload/add'
const url2 = 'http://jxqft.com:9000/shaokx'
const files1 = ref<UTSJSONObject[]>([{
id: '1',
url: 'http://gips0.baidu.com/it/u=1690853528,2506870245&fm=3028&app=3028&f=JPEG&fmt=auto?w=1024&h=1024'
},{
id: '2',
url: 'http://gips2.baidu.com/it/u=195724436,3554684702&fm=3028&app=3028&f=JPEG&fmt=auto?w=1280&h=960'
}] )
const files2 = ref<UTSJSONObject[]>([])
const files3 = ref<UTSJSONObject[]>([])
const files4 = ref<UTSJSONObject[]>([])
const files5 = ref<UTSJSONObject[]>([])
const formData = ref<UTSJSONObject>({
'bucket': "shaokx",
'key': "/newhouse/20240718102240.png",
'policy': "eyJjb25kaXRpb25zIjpbWyJlcSIsIiRidWNrZXQiLCJzaGFva3giXSxbImVxIiwiJGtleSIsIi9uZXdob3VzZS8yMDI0MDcxODEwMjI0MC5wbmciXSxbImVxIiwiJHgtYW16LW1ldGEtZGVzY3JpcHRpb24iLCLmlYjmnpzlm74iXSxbImVxIiwiJHgtYW16LWRhdGUiLCIyMDI0MDcxOFQwMjIyNDBaIl0sWyJlcSIsIiR4LWFtei1hbGdvcml0aG0iLCJBV1M0LUhNQUMtU0hBMjU2Il0sWyJlcSIsIiR4LWFtei1jcmVkZW50aWFsIiwiS3ZxMnZoU3VCODZTeU1RalBPTVkvMjAyNDA3MTgvdXMtZWFzdC0xL3MzL2F3czRfcmVxdWVzdCJdXSwiZXhwaXJhdGlvbiI6IjIwMjQtMDctMTlUMDI6MjI6MDAuMjIyWiJ9",
'x-amz-algorithm': "AWS4-HMAC-SHA256",
'x-amz-credential': "Kvq2vhSuB86SyMQjPOMY/20240718/us-east-1/s3/aws4_request",
'x-amz-date': "20240718T022240Z",
'x-amz-meta-description': "效果图",
'x-amz-signature': "650b89ad802c2aab3b05536b30c02b4ac5116454421e9662c0b4d1a69069f4c7"
})
function change1(files: UxUploadFile[]) {
console.log(files);
}
function change2(files: UxUploadFile[]) {
console.log(files);
}
function change3(files: UxUploadFile[]) {
console.log(files);
}
function change4(files: UxUploadFile[]) {
console.log(files);
}
function change5(files: UxUploadFile[]) {
console.log(files);
}
function error(err: string) {
uni.showToast({
title: err,
icon: 'none'
})
}
function beforeUpload(path: string): UTSJSONObject | null {
return null
}
function afterUpload(data: string):string {
uni.hideLoading()
let res = JSON.parseObject(data)
let d = res?.getJSON('data')
return d?.getString('url') ?? ''
}
async function beforeDel(index: number, file: UxUploadFile):Promise<boolean> {
return new Promise<boolean>((resolve) => {
uni.showModal({
content: '确定删除吗?',
success: (e) => {
if(e.confirm) {
resolve(true)
} else {
resolve(false)
}
}
})
})
}
function onPreview(index: number, files: UxUploadFile[]) {
let arr = files.filter((e):boolean => e.status == 'success').map((e): string => e.path)
uni.previewImage({
urls: arr,
current: index
})
// 视频未处理
}
function submit() {
uni.showLoading({
title: '上传中...',
})
uxUploadRef.value?.$callMethod('upload')
}
const showDoc = ref(false)
function onDoc() {
plus.openWeb({
title: '在线文档',
url: 'https://www.uxframe.cn/component/upload.html',
// blur: 1,
success: () => {
showDoc.value = true
},
complete: () => {
showDoc.value = false
}
})
}
onLoad((e) => {
title.value = e['title'] ?? ''
})
</script>
css
<style lang="scss">
</style>
<style lang="scss">
</style>