Attachments 输入附件
用于展示一组附件信息集合。
何时使用
Attachments 组件用于需要展示一组附件信息集合的场景。
代码演示
基本
基础用法,可以通过 getDropContainer
支持拖拽上传。
Full screen drop
ts
<script setup lang="ts">
import type { AttachmentProps } from '@artmate/chat'
import { Attachment, Sender } from '@artmate/chat'
import { Link, Promotion } from '@element-plus/icons-vue'
import { ElButton, ElIcon, ElMessage, ElSpace, ElSwitch } from 'element-plus'
import { computed, ref } from 'vue'
const fullScreenDrop = ref(false)
const divRef = ref<HTMLElement>()
const getDropContainer = computed<() => HTMLElement | null>(() => {
const el = fullScreenDrop.value ? document.body : (divRef.value as HTMLElement)
return () => el
})
const value = ref('')
const FileChange: AttachmentProps['onChange'] = ({ file }) => {
ElMessage.success(`Mock upload: ${file.name}`)
}
</script>
<template>
<div ref="divRef">
<ElSpace direction="vertical" fill style="width: 100%">
<Sender v-model="value">
<template #prefix>
<Attachment :get-drop-container="getDropContainer" @change="FileChange">
<ElButton text style="padding: 0px 7px">
<ElIcon size="20">
<Link />
</ElIcon>
</ElButton>
<template #icon>123</template>
</Attachment>
</template>
<template #actions>
<ElButton circle type="primary" @click="fullScreenDrop = !fullScreenDrop">
<ElIcon color="white">
<Promotion />
</ElIcon>
</ElButton>
</template>
</Sender>
<ElSwitch
v-model="fullScreenDrop"
inline-prompt
active-text="Full screen drop"
inactive-text="Full screen drop"
/>
</ElSpace>
</div>
</template>
<style lang="scss" scoped></style>
查看源代码
占位信息
修改占位信息。
Click or Drop files here
Support file type: image, video, audio, document, etc.
Click or Drop files here
ts
<script setup lang="ts">
import type { AttachmentProps } from '@artmate/chat'
import { Attachment } from '@artmate/chat'
import { UploadFilled } from '@element-plus/icons-vue'
import { ElButton, ElIcon, ElSpace } from 'element-plus'
import { computed, ref } from 'vue'
const presetFiles: AttachmentProps['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: 'success',
size: 123456,
url: 'http://www.baidu.com/yyy.png',
descriptions: 'Customize description',
},
{
uid: 3,
name: 'upload error with long text file name.zip',
status: 'fail',
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: 'ready',
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: 'fail',
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',
},
]
const items = ref<AttachmentProps['items']>([])
const sharedAttachmentProps = computed<AttachmentProps>(() => ({
beforeUpload: () => false,
items: items.value,
onChange: ({ fileList }) => {
console.log('onChange:', fileList)
items.value = fileList
},
}))
function setItems(value: AttachmentProps['items']) {
items.value = value
}
</script>
<template>
<ElSpace direction="vertical" style="width: 100%">
<Attachment v-bind="sharedAttachmentProps">
<template #icon>
<ElIcon>
<UploadFilled />
</ElIcon>
</template>
<template #title>Click or Drop files here</template>
<template #description>Support file type: image, video, audio, document, etc.</template>
</Attachment>
<Attachment v-bind="sharedAttachmentProps">
<template #icon>
<ElIcon color="#1677ff" size="80">
<UploadFilled />
</ElIcon>
</template>
<template #title>
<h1>Click or Drop files here</h1>
</template>
<template #description>
<ElButton type="primary" style="margin-top: 10px">Do Upload</ElButton>
</template>
</Attachment>
<ElSpace>
<ElButton type="primary" :disabled="!!items?.length" @click="setItems(presetFiles)">
Fill Files
</ElButton>
<ElButton :disabled="!items?.length" @click="setItems([])">Reset Files</ElButton>
</ElSpace>
</ElSpace>
</template>
<style lang="scss" scoped></style>
查看源代码
超出样式
控制附件超出区域长度时的展示方式。
Data
Disabled
Click or Drop files here
Support file type: image, video, audio, document, etc.
ts
<script setup lang="ts">
import type { AttachmentProps } from '@artmate/chat'
import { Attachment } from '@artmate/chat'
import { UploadFilled } from '@element-plus/icons-vue'
import { ElIcon, ElSegmented, ElSpace, ElSwitch } from 'element-plus'
import { ref } from 'vue'
const presetFiles: AttachmentProps['items'] = Array.from({ length: 30 }).map((_, index) => ({
uid: index,
name: `file-${index}.jpg`,
status: 'ready',
thumbUrl: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
}))
const sizeOptions = [
{ value: 'wrap', label: 'Wrap' },
{ value: 'scrollX', label: 'Scroll X' },
{ value: 'scrollY', label: 'Scroll Y' },
]
const overflow = ref<AttachmentProps['overflow']>('wrap')
const items = ref<AttachmentProps['items']>(presetFiles)
const disabled = ref(false)
const showData = ref(true)
function dataChange(value: string | number | boolean) {
if (value) {
items.value = presetFiles
}
else {
items.value = []
}
}
function FileChange() {}
</script>
<template>
<div>
<div class="top">
<ElSegmented v-model="overflow" :options="sizeOptions" style="margin-inline-end: auto" />
<ElSpace>
<ElSwitch
v-model="showData"
inline-prompt
active-text="Data"
inactive-text="Data"
@change="dataChange"
/>
<ElSwitch
v-model="disabled"
inline-prompt
active-text="Disabled"
inactive-text="Disabled"
/>
</ElSpace>
</div>
<Attachment :overflow="overflow" :items="items" :disabled="disabled" @change="FileChange">
<template #icon>
<ElIcon>
<UploadFilled />
</ElIcon>
</template>
<template #title>
Click or Drop files here
</template>
<template #description>
Support file type: image, video, audio, document, etc.
</template>
</Attachment>
</div>
</template>
<style lang="scss" scoped>
.top {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
padding: 0 10px;
}
</style>
查看源代码
组合示例
配合 Sender.Header 使用,在对话中插入附件。
Attachments
Upload Sample
Click or drag files to this area to upload
ts
<script setup lang="ts">
import { Attachment, Sender, SenderHeader } from '@artmate/chat'
import { Link, Promotion, UploadFilled } from '@element-plus/icons-vue'
import { ElButton, ElIcon, ElMessage, ElSpace } from 'element-plus'
import { ref } from 'vue'
const value = ref('')
const open = ref(true)
function submit() {
ElMessage.success('Send message successfully!')
}
</script>
<template>
<ElSpace style="width: 100%; height: 300px" fill alignment="end">
<Sender v-model="value" @on-submit="submit">
<template #header>
<SenderHeader title="Attachments" :open="open">
<template #default>
<Attachment title="Upload files">
<template #icon>
<ElIcon size="50">
<UploadFilled />
</ElIcon>
</template>
<template #title>Upload Sample</template>
<template #description>Click or drag files to this area to upload</template>
</Attachment>
</template>
</SenderHeader>
</template>
<template #prefix>
<ElButton link @click="open = !open">
<ElIcon>
<Link />
</ElIcon>
</ElButton>
</template>
<template #actions>
<ElButton circle type="primary" @click="submit">
<ElIcon color="white">
<Promotion />
</ElIcon>
</ElButton>
</template>
</Sender>
</ElSpace>
</template>
<style lang="scss" scoped></style>
查看源代码
文件卡片
单独的文件卡片,用于一些展示场景。
excel-file
.xlsx
109 KB
word-file
.docx
217 KB
pdf-file
.pdf
434 KB
ppt-file
.pptx
543 KB
video-file
.mp4
651 KB
audio-file
.mp3
760 KB
zip-file
.zip
868 KB
markdown-file
.md
Custom description here
ts
<script setup lang="ts">
import type { FileListCardProps } from '@artmate/chat'
import { FileCard } from '@artmate/chat'
import { ElSpace } from 'element-plus'
const filesList: FileListCardProps['item'][] = [
{
uid: 1,
name: 'excel-file.xlsx',
size: 111111,
},
{
uid: 2,
name: 'word-file.docx',
size: 222222,
},
{
uid: 4,
name: 'pdf-file.pdf',
size: 444444,
},
{
uid: 5,
name: 'ppt-file.pptx',
size: 555555,
},
{
uid: 6,
name: 'video-file.mp4',
size: 666666,
},
{
uid: 7,
name: 'audio-file.mp3',
size: 777777,
},
{
uid: 8,
name: 'zip-file.zip',
size: 888888,
},
{
uid: 9,
name: 'markdown-file.md',
size: 999999,
description: 'Custom description here',
},
{
uid: 10,
name: 'image-file.png',
thumbUrl: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
size: 123456,
},
]
</script>
<template>
<ElSpace direction="vertical" alignment="flex-start">
<template v-for="file in filesList" :key="file.uid">
<FileCard :item="file" disabled />
</template>
</ElSpace>
</template>
<style lang="scss" scoped></style>
查看源代码
Attachments Props
继承 element-plus ElUpload 属性。
属性 | 说明 | 类型 | 默认值 | 版本 |
---|---|---|---|---|
classNames | 自定义样式类名 | Record<string, string> | - | - |
disabled | 是否禁用 | boolean | false | - |
getDropContainer | 设置拖拽时,可以释放文件的区域 | () => HTMLElement | - | - |
items | 附件列表,同 Upload fileList | Attachment[] | - | - |
overflow | 文件列表超出时样式 | 'wrap' | 'scrollX' | 'scrollY' | - | - |
placeholder | 没有文件时的占位信息 | PlaceholderType | ((type: 'inline' | 'drop') => PlaceholderType) | - | - |
rootClassName | 根节点的样式类名 | string | - | - |
rootStyle | 根节点的样式对象 | CSSProperties | - | - |
styles | 自定义样式对象 | Record<string, CSSProperties> | - | - |
Attachments Slots
插槽名 | 说明 | 类型 |
---|---|---|
icon | icon区域内容 | - |
title | 标题区域内容 | - |
placeholder | 没有文件时的占位信息 | - |
Attachments Expose
属性 | 说明 | 类型 | 版本 |
---|---|---|---|
nativeElement | 获取原生节点 | HTMLElement | - |
upload | 手工调用上传文件 | (file: UploadFile) => void | - |
Attachments.FileCard Props
属性 | 说明 | 类型 | 默认值 | 版本 |
---|---|---|---|---|
item | 附件,同 Upload UploadFile | Attachment | - | - |
onRemove | 附件移除时的回调函数 | (item: Attachment) => void | - | - |