Upload
上传组件,Upload组件经过了重构,虽然总体上与之前总体是兼容的,但是添加了很多的默认行为。具体参见API部分。
上传组件的类型可以分为两个种:一种是仅提供选择文件的功能,文件数据会在用户点击提交时随表单的From对象一起上传给后端;另一种是在提交表单之前先上传至后端(大部分情况下是提前上传至OSS),在提交表单时不提交文件的二进制信息而是获取桶内对应文件的url或者其他可以获取已上传文件的字符串。本组件对这两种行为做了不同的处理。当组件的action属性为'#'且没有配置httpRequest属性时会将属性当做第一种情况处理,onChange事件会在fileList的status改变时触发。当用户配置了两者中的任意一项时会当做第二种情况处理,onChange事件会在请求完成(即fileList中有任意一项的response属性发生改变)时触发。
显示给用户看的文件列表与表单最后提交的值是分离的、是单向的,即当fileList(dataSource)改变时会触发onChange事件(修改Field的value),但是当value改变时不会修改dataSource,这是因为大部分情况下这种改动都是单向的:用户添加删除选择的文件时从fileList中获取对应的value。只有一种情况下是例外的即表单信息的反显:在处理反显时除了需要设置Field的value外还需要自己组装组件的fileList(dataSource),具体需要将fileList组装到什么程度可以根据业务需要自己决定。
Markup Schema 案例
<script lang="ts" setup>
import { createForm } from '@formily/core'
import {
Form,
FormButtonGroup,
FormItem,
Submit,
Upload,
} from '@silver-formily/element-plus'
import { createSchemaField } from '@silver-formily/vue'
import { ElButton } from 'element-plus'
import { h } from 'vue'
function UploadButton() {
return h(ElButton, {}, { default: () => '上传图片' })
}
const form = createForm()
const { SchemaField, SchemaArrayField } = createSchemaField({
components: {
FormItem,
Upload,
},
})
async function onSubmit(value) {
console.log(value)
}
</script>
<template>
<Form :form="form" :label-col="4" :wrapper-col="10">
<SchemaField>
<SchemaArrayField
name="upload"
title="上传"
x-decorator="FormItem"
x-component="Upload"
:x-component-props="{
action: 'https://run.mocky.io/v3/4ddf3c65-5202-4b56-87ad-ef7314e84fdc',
textContent: '上传',
}"
required
/>
<SchemaArrayField
name="upload2"
title="卡片上传"
x-decorator="FormItem"
x-component="Upload"
:x-component-props="{
listType: 'picture-card',
action: '#',
}"
required
/>
<SchemaArrayField
name="upload3"
title="拖拽上传"
x-decorator="FormItem"
x-component="Upload"
:x-component-props="{
action: 'https://formily-vue.free.beeceptor.com/file',
textContent: '将文件拖到此处,或者点击上传',
drag: true,
}"
required
/>
<SchemaArrayField
name="custom"
title="自定义按钮"
x-decorator="FormItem"
x-component="Upload"
:x-component-props="{
action: 'https://formily-vue.free.beeceptor.com/file',
}"
required
:x-content="UploadButton"
/>
</SchemaField>
<FormButtonGroup align-form-item>
<Submit @submit="onSubmit">
提交
</Submit>
</FormButtonGroup>
</Form>
</template>JSON Schema 案例
<script lang="ts" setup>
import { createForm } from '@formily/core'
import {
Form,
FormButtonGroup,
FormItem,
Submit,
Upload,
} from '@silver-formily/element-plus'
import { createSchemaField } from '@silver-formily/vue'
import { ElButton } from 'element-plus'
import { h } from 'vue'
function UploadButton() {
return h(ElButton, {}, { default: () => '上传图片' })
}
const schema = {
type: 'object',
properties: {
base: {
'type': 'array',
'title': '上传',
'x-decorator': 'FormItem',
'x-component': 'Upload',
'x-component-props': {
action: 'https://formily-vue.free.beeceptor.com/file',
textContent: '上传',
},
'required': true,
},
card: {
'type': 'array',
'title': '卡片上传',
'x-decorator': 'FormItem',
'x-component': 'Upload',
'x-component-props': {
listType: 'picture-card',
action: 'https://formily-vue.free.beeceptor.com/file',
},
'required': true,
},
drag: {
'type': 'array',
'title': '拖拽上传',
'x-decorator': 'FormItem',
'x-component': 'Upload',
'x-component-props': {
action: 'https://formily-vue.free.beeceptor.com/file',
textContent: '将文件拖到此处,或者点击上传',
drag: true,
},
'required': true,
},
custom: {
'type': 'array',
'title': '自定义按钮',
'x-decorator': 'FormItem',
'x-component': 'Upload',
'x-component-props': {
action: 'https://formily-vue.free.beeceptor.com/file',
},
'x-content': UploadButton,
'required': true,
},
},
}
const form = createForm()
const { SchemaField } = createSchemaField({
components: {
FormItem,
Upload,
},
})
async function onSubmit(value) {
console.log(value)
}
</script>
<template>
<Form :form="form" :label-col="4" :wrapper-col="10">
<SchemaField :schema="schema" />
<FormButtonGroup align-form-item>
<Submit @submit="onSubmit">
提交
</Submit>
</FormButtonGroup>
</Form>
</template>Template 案例
<script lang="ts" setup>
import { createForm } from '@formily/core'
import {
Form,
FormButtonGroup,
FormItem,
Submit,
Upload,
} from '@silver-formily/element-plus'
import { ArrayField } from '@silver-formily/vue'
import { ElButton } from 'element-plus'
import { h } from 'vue'
function UploadButton() {
return h(ElButton, {}, { default: () => '上传图片' })
}
const form = createForm()
async function onSubmit(value) {
console.log(value)
}
</script>
<template>
<Form :form="form" :label-col="4" :wrapper-col="10">
<ArrayField
name="upload"
title="上传"
:decorator="[FormItem]"
:component="[
Upload,
{
action: 'https://formily-vue.free.beeceptor.com/file',
textContent: '上传',
},
]"
required
/>
<ArrayField
name="upload2"
title="卡片上传"
:decorator="[FormItem]"
:component="[
Upload,
{
listType: 'picture-card',
action: 'https://formily-vue.free.beeceptor.com/file',
},
]"
required
/>
<ArrayField
name="upload3"
title="拖拽上传"
:decorator="[FormItem]"
:component="[
Upload,
{
action: 'https://formily-vue.free.beeceptor.com/file',
textContent: '将文件拖到此处,或者点击上传',
drag: true,
},
]"
required
/>
<ArrayField
name="custom"
title="自定义按钮"
:decorator="[FormItem]"
:component="[
Upload,
{
action: 'https://formily-vue.free.beeceptor.com/file',
},
]"
required
>
<UploadButton />
</ArrayField>
<FormButtonGroup align-form-item>
<Submit @submit="onSubmit">
提交
</Submit>
</FormButtonGroup>
</Form>
</template>API
Props
提示
现在组件的
fileList属性现在会映射为Field的dataSource属性,而不是之前的value属性,当dataSource(即fileList)改变时会触发onChange事件,value会经过formatValue函数处理。在
limit为1时会自动替换掉之前的文件,这部分逻辑无法覆写。如果组件的
accept属性包含image字符且fileList中的项提供了url属性则会自动开启图片预览功能,想要禁用此功能可以配置onPreview为一个空函数。
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| textContent | 上传按钮的文本内容,在不同的上传模式下显示位置不同 | string | '' |
| errorAdaptor | 错误信息适配器,用于自定义错误信息的展示格式 | Function | error => error?.message |
| formatValue 1.0.0 | 格式化函数,用于将文件列表转换为表单最终提交的值 | Function | fileList => fileList |
| fileList 1.0.0 | 文件列表,映射为dataSource,ElUpload的 fileList 属性 | array | [] |
| imageViewerProps 1.0.0 | 图片预览器的属性配置,当上传图片时可用于自定义预览行为 | object | { teleported: true, showProgress: true } |
onChange事件与onUpdate:fileList事件被占用,请勿使用。其余属性与事件请参考 https://cn.element-plus.org/zh-CN/component/upload.html
插槽 1.0.0
组件继承了ElUpload的所有插槽。
提示
可以使用textContent属性list-type属性drag属性快速生成本来需要通过插槽实现的交互,具体请参考demo。
获取实例 1.0.0
用于获取ElUpload实例,具体暴露的方法请参考element-plus文档。
const uploadRef: Ref<UploadInstance> = fieldRef.value.invoke('getElUploadRef')