Attachments
Used to display a collection of attachment information.
When to use
The Attachments component is used in scenarios where there is a need to display a set of attachment information.
Examples
Basic
Placeholder
Click or Drop files here
Support file type: image, video, audio, document, etc.Custom Placeholder Node
Placeholder
Customize the placeholder.
ts
<script setup lang="tsx">
import { CloudUploadOutlined } from '@ant-design/icons-vue';
import { Button, Flex, Result, theme } from 'ant-design-vue';
import { Attachments, type AttachmentsProps } from 'ant-design-x-vue';
import { computed, type CSSProperties, ref } from 'vue';
defineOptions({ name: 'AXAttachmentPlaceholder' });
const presetFiles: AttachmentsProps['items'] = [
{
uid: '1',
name: 'uploading file.xlsx',
status: 'uploading',
url: 'http://www.baidu.com/xxx.png',
percent: 93,
},
{
uid: '2',
name: 'uploaded file.docx',
status: 'done',
size: 123456,
description: 'Customize description',
url: 'http://www.baidu.com/yyy.png',
},
{
uid: '3',
name: 'upload error with long text file name.zip',
status: 'error',
response: 'Server Error 500', // custom error message to show
url: 'http://www.baidu.com/zzz.png',
},
{
uid: '4',
name: 'image uploading preview.png',
status: 'uploading',
percent: 33,
thumbUrl: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
},
{
uid: '5',
name: 'image done preview.png',
status: 'done',
size: 123456,
thumbUrl: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
},
{
uid: '6',
name: 'image error preview.png',
status: 'error',
response: 'Server Error 500', // custom error message to show
thumbUrl: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
},
];
type ExtractFunc<T> = T extends (...args: any) => any ? T : never;
const getPlaceholderFn = (
inlinePlaceholder: ReturnType<ExtractFunc<AttachmentsProps['placeholder']>>,
) => {
return (type: 'inline' | 'drop') =>
type === 'drop'
? {
title: 'Drop file here',
}
: inlinePlaceholder;
};
const { token } = theme.useToken();
const items = ref<AttachmentsProps['items']>([]);
const sharedBorderStyle = computed<CSSProperties>(() => ({
borderRadius: token.value.borderRadius,
overflow: 'hidden',
background: token.value.colorBgContainer,
}));
const sharedAttachmentProps = computed<AttachmentsProps>(() => ({
beforeUpload: () => false,
items: items.value,
onChange: ({ fileList }) => {
console.log('onChange:', fileList);
items.value = fileList;
},
}));
defineRender(() => {
return (
<Flex
vertical
gap="middle"
style={{
padding: token.value.padding,
background: token.value.colorBgContainerDisabled,
}}
>
<div style={sharedBorderStyle.value}>
<Attachments
{...sharedAttachmentProps.value}
placeholder={getPlaceholderFn({
icon: <CloudUploadOutlined />,
title: 'Click or Drop files here',
description: 'Support file type: image, video, audio, document, etc.',
})}
/>
</div>
<div style={sharedBorderStyle.value}>
<Attachments
{...sharedAttachmentProps.value}
placeholder={getPlaceholderFn(
<Result
title="Custom Placeholder Node"
icon={<CloudUploadOutlined />}
extra={<Button type="primary">Do Upload</Button>}
style={{ padding: 0 }}
/>,
)}
/>
</div>
<Flex gap="middle">
<Button
style={{ flex: '1 1 50%' }}
disabled={!!items.value.length}
type="primary"
onClick={() => {
items.value = presetFiles
}}
>
Fill Files
</Button>
<Button
style={{ flex: '1 1 50%' }}
disabled={!items.value.length}
onClick={() => {
items.value = []
}}
>
Reset Files
</Button>
</Flex>
</Flex>
)
});
</script>
Hide source
Overflow style

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview

Preview
Click or Drop files here
Support file type: image, video, audio, document, etc.Overflow style
Control how attachments overflow.
ts
<script setup lang="tsx">
import { CloudUploadOutlined } from '@ant-design/icons-vue';
import { Flex, Segmented, Switch } from 'ant-design-vue';
import { Attachments, type AttachmentsProps } from 'ant-design-x-vue';
import { ref } from 'vue';
defineOptions({ name: 'AXAttachmentOverflow' });
const presetFiles: AttachmentsProps['items'] = Array.from({ length: 30 }).map((_, index) => ({
uid: String(index),
name: `file-${index}.jpg`,
status: 'done',
thumbUrl: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
}));
const overflow = ref<AttachmentsProps['overflow']>('wrap');
const items = ref<AttachmentsProps['items']>(presetFiles);
const disabled = ref(false);
defineRender(() => {
return (
<Flex vertical gap="middle">
<Flex gap="middle" align="center">
<Segmented
options={[
{ value: 'wrap', label: 'Wrap' },
{ value: 'scrollX', label: 'Scroll X' },
{ value: 'scrollY', label: 'Scroll Y' },
]}
value={overflow.value}
onChange={(v) => {
overflow.value = v as AttachmentsProps['overflow'];
}}
style={{ marginInlineEnd: 'auto' }}
/>
<Switch
checked={items.value.length !== 0}
onChange={() => {
items.value = items.value.length ? [] : presetFiles
}}
checkedChildren="Data"
unCheckedChildren="Data"
/>
<Switch
checked={disabled.value}
onChange={(v) => {
disabled.value = v as boolean;
}}
checkedChildren="Disabled"
unCheckedChildren="Disabled"
/>
</Flex>
<Attachments
overflow={overflow.value}
items={items.value}
onChange={(info) => {
items.value = info.fileList
}}
beforeUpload={() => false}
placeholder={{
icon: <CloudUploadOutlined />,
title: 'Click or Drop files here',
description: 'Support file type: image, video, audio, document, etc.',
}}
disabled={disabled.value}
/>
</Flex>
)
})
</script>
Hide source
Combined example
Select files by type
File card
Custom card icon
API
General properties reference: General Properties.
Attachments Props
Inherits antdv Upload properties.
| Prop | Description | Type | Default | Version |
|---|---|---|---|---|
| classNames | Custom style class names, see below | Record<string, string> | - | - |
| disabled | Whether disabled | boolean | false | - |
| getDropContainer | Set the area where the file can be released when dragging | () => HTMLElement | - | - |
| items | attachment list, same as Upload fileList | Attachment[] | - | - |
| overflow | Style when the file list exceeds | 'wrap' | 'scrollX' | 'scrollY' | - | - |
| placeholder | Placeholder information when there is no file | PlaceholderType | ((type: 'inline' | 'drop') => PlaceholderType) | - | - |
| rootClassName | Root class name | string | - | - |
| rootStyle | Root style object | CSSProperties | - | - |
| styles | Custom style object, see below | Record<string, CSSProperties> | - | - |
| imageProps | Image properties, same as antdv Image properties | ImageProps | - | - |
tsx
interface PlaceholderType {
icon?: VNode;
title?: VNode | string;
description?: VNode | string;
}Attachments Slots
| Slot | Description | Type |
|---|---|---|
| placeholder | Placeholder information when there is no file | { type: "inline" | "drop" } |
Attachments Expose
| Prop | Description | Type | Version |
|---|---|---|---|
| nativeElement | Get native node | HTMLElement | - |
| fileNativeElement | Get the native input node for file upload | HTMLInputElement | null | - |
| upload | Manually call to upload files | (file: File | File[] | FileList) => void | - |
| select | Manually open the file selector (can override accept / multiple) | (options: { accept?: string; multiple?: boolean }) => void | - |
Attachments.FileCard Props
| Prop | Description | Type | Default | Version |
|---|---|---|---|---|
| item | Attachment, same as Upload UploadFile | Attachment | - | - |
| onRemove | Callback when clicking to remove a file. If the return value is false, the file will not be removed. It also supports returning a Promise object; if the Promise resolves with false or rejects, the file will not be removed | (item: Attachment) => boolean | Promise | - |
| icon | Custom icon | VNode | PresetIcons | - |
| type | Defines the file type. When the type is image, it will display in image preview mode | 'file' | 'image' | file |
ts
type PresetIcons = 'default' | 'excel' | 'image' | 'markdown' | 'pdf' | 'ppt' | 'word' | 'zip' | 'video' | 'audio';Semantic DOM
Upload File
Drag or click to upload file.placeholder
占位符

Preview

Preview

Preview
list
列表容器item
列表项upload
上传按钮
The semantic keys for Vue
AttachmentsclassNames/stylesarelist/item/placeholder/upload(different from some FileCard semantics in React 2.10, here only records the keys actually exposed by Vue).
Design Token
| Token | Description | Type | Default |
|---|---|---|---|
| colorBgPlaceholderHover | Background color on placeholder hover | string | rgba(colorBgContainer, 0.85) |
Contributors
Contributors
Loading contributors…