Upload
上传组件,Upload组件经过了重构,虽然总体上与之前总体是兼容的,但是添加了很多的默认行为。具体参见API部分。
上传组件的类型可以分为两种:一种是仅提供选择文件的功能,文件数据会在用户点击提交时随表单的 Form 对象一起上传给后端;另一种是在提交表单之前先上传至后端(大部分情况下是提前上传至 OSS),在提交表单时不提交文件的二进制信息,而是提交文件 URL 或其他可用于获取已上传文件的标识。具体的上传行为由 Element Plus Upload 的 action、httpRequest 等属性控制。
显示给用户的文件列表与表单最终提交的值是分离的,并且只进行单向转换。 ElUpload 的文件列表发生变化时,组件会在内部将最新列表同步到 Field.dataSource,再通过 formatValue 转换,并触发 update:modelValue 更新 Field.value;Field.value 变化时不会反向修改 Field.dataSource。
表单数据反显是需要手动处理的例外场景:除了设置 Field.value,还需要根据业务需要组装并设置组件的 fileList(即 Field.dataSource)。
Markup Schema 案例
<script lang="ts" setup>
import { createForm } from '@silver-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: Record<string, any>) {
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 '@silver-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: Record<string, any>) {
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 '@silver-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: Record<string, any>) {
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,而不是Field.value。当dataSource(即fileList)改变时,组件会使用formatValue生成表单值,并通过update:modelValue更新Field.value。在
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')