Appearance
FilePreview 文件预览
用于根据文件类型自动渲染对应的预览组件,支持图片、视频、音频、PDF、EML、Markdown、文本等文件类型的预览。
动态切换
通过下拉选择切换不同类型的文件,演示 url 从 undefined / null 变化时的容错处理。
文件类型:
当前 url:
/files/images/1.svg<template>
<div class="demo-dynamic">
<div class="demo-dynamic__controls">
<div class="demo-dynamic__label">文件类型:</div>
<el-select v-model="selectedType" placeholder="请选择类型" clearable style="width: 340px">
<el-option-group
v-for="group in groups"
:key="group.label"
:label="group.label"
>
<el-option
v-for="item in group.options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-option-group>
</el-select>
</div>
<div class="demo-dynamic__preview">
<hx-file-preview
:url="currentUrl"
preview-width="240px"
preview-height="160px"
/>
</div>
<div class="demo-dynamic__info" v-if="currentUrl">
当前 url: <code>{{ currentUrl }}</code>
</div>
<div class="demo-dynamic__info demo-dynamic__info--null" v-else>
当前 url: <code>null</code>(无文件,组件展示空状态图标)
</div>
</div>
</template>
<script setup lang="ts">
import { computed, ref } from 'vue'
import { HxFilePreview as FilePreview } from "@whhx/ui"
const BASE = '/files'
interface FileOption {
label: string
value: string
}
interface OptionGroup {
label: string
options: FileOption[]
}
const groups: OptionGroup[] = [
{
label: '图片',
options: [
{ label: 'svg', value: 'svg' },
{ label: 'webp', value: 'webp' },
{ label: 'png', value: 'png' },
{ label: 'jpg', value: 'jpg' },
{ label: 'jpeg', value: 'jpeg' },
{ label: 'gif', value: 'gif' },
{ label: 'bmp', value: 'bmp' },
{ label: 'ico', value: 'ico' },
],
},
{
label: '视频',
options: [
{ label: 'mp4', value: 'mp4' },
{ label: 'flv', value: 'flv' },
{ label: 'm3u8', value: 'm3u8' },
{ label: 'webm', value: 'webm' },
{ label: 'mov', value: 'mov' },
{ label: 'avi', value: 'avi' },
{ label: 'wmv', value: 'wmv' },
{ label: 'ogg', value: 'ogg_video' },
],
},
{
label: '音频',
options: [
{ label: 'mp3', value: 'mp3' },
{ label: 'wav', value: 'wav' },
{ label: 'ogg', value: 'ogg_audio' },
{ label: 'aac', value: 'aac' },
{ label: 'flac', value: 'flac' },
{ label: 'm4a', value: 'm4a' },
],
},
{
label: '文档',
options: [
{ label: 'pdf', value: 'pdf' },
{ label: 'eml', value: 'eml' },
{ label: 'md', value: 'md' },
],
},
{
label: '文本',
options: [
{ label: 'txt', value: 'txt' },
{ label: 'yaml', value: 'yaml' },
{ label: 'yml', value: 'yml' },
{ label: 'json', value: 'json' },
{ label: 'xml', value: 'xml' },
{ label: 'csv', value: 'csv' },
],
},
{
label: '其他',
options: [
{ label: 'null', value: 'null' },
],
},
]
const selectedType = ref('svg')
// 所有路径均为占位符,真实文件由使用者自行补充到 server/public/files 对应目录
const typeMap: Record<string, string> = {
svg: `${BASE}/images/1.svg`,
webp: `${BASE}/images/1.webp`,
png: `${BASE}/images/1.png`,
jpg: `${BASE}/images/1.jpg`,
jpeg: `${BASE}/images/1.jpeg`,
gif: `${BASE}/images/1.gif`,
bmp: `${BASE}/images/1.bmp`,
ico: `${BASE}/images/1.ico`,
mp4: `${BASE}/videos/1.mp4`,
flv: `${BASE}/videos/1.flv`,
m3u8: `${BASE}/videos/1.m3u8`,
webm: `${BASE}/videos/1.webm`,
mov: `${BASE}/videos/1.mov`,
avi: `${BASE}/videos/1.avi`,
wmv: `${BASE}/videos/1.wmv`,
ogg_video: `${BASE}/videos/1.ogg`,
mp3: `${BASE}/audio/1.mp3`,
wav: `${BASE}/audio/1.wav`,
ogg_audio: `${BASE}/audio/1.ogg`,
aac: `${BASE}/audio/1.aac`,
flac: `${BASE}/audio/1.flac`,
m4a: `${BASE}/audio/1.m4a`,
pdf: `${BASE}/pdf/1.pdf`,
eml: `${BASE}/eml/1.eml`,
md: `${BASE}/markdown/sample.md`,
txt: `${BASE}/text/sample.txt`,
yaml: `${BASE}/yaml/sample.yaml`,
yml: `${BASE}/yaml/sample.yml`,
json: `${BASE}/json/1.json`,
xml: `${BASE}/xml/sample.xml`,
csv: `${BASE}/csv/sample.csv`,
}
const currentUrl = computed(() => {
if (selectedType.value === 'null') return null as any
return typeMap[selectedType.value] ?? null as any
})
</script>
<style lang="scss" scoped>
.demo-dynamic {
display: flex;
flex-direction: column;
gap: 16px;
&__controls {
display: flex;
align-items: center;
gap: 12px;
}
&__label {
font-size: 14px;
color: var(--el-text-color-primary);
font-weight: 500;
flex-shrink: 0;
}
&__preview {
display: flex;
align-items: flex-start;
}
&__info {
font-size: 13px;
color: var(--el-text-color-regular);
display: flex;
align-items: center;
gap: 6px;
code {
background: var(--el-fill-color-light);
padding: 2px 8px;
border-radius: 4px;
font-size: 12px;
color: var(--el-color-danger);
word-break: break-all;
}
&--null code {
color: var(--el-color-danger);
background: var(--el-color-danger-light-9);
}
}
}
</style>
图片预览
自动识别 jpg、png、gif、webp、svg 等图片格式并渲染缩略图。
jpg: webp:
<template>
<div class="demo-row">
jpg:
<hx-file-preview
url="/files/images/1.jpg"
preview-width="120px"
preview-height="80px"
/>
webp:
<hx-file-preview
url="/files/images/1.webp"
preview-width="120px"
preview-height="80px"
/>
</div>
</template>
<script setup lang="ts">
import { HxFilePreview as FilePreview } from "@whhx/ui"
</script>
视频预览
自动识别 mp4、flv、m3u8、webm、mov 等视频格式并渲染视频播放器。
mp4: flv:
加载中...
▶
<template>
<div class="demo-row">
mp4:
<hx-file-preview
url="/files/videos/1.mp4"
preview-width="240px"
preview-height="160px"
/>
flv:
<hx-file-preview
url="/files/videos/1.flv"
preview-width="240px"
preview-height="160px"
/>
</div>
</template>
<script setup lang="ts">
import { HxFilePreview as FilePreview } from "@whhx/ui"
</script>
音频预览
自动识别 mp3、wav、ogg、aac、flac 等音频格式并渲染音频播放器。
mp3:
音频
<template>
<div class="demo-row">
mp3:
<hx-file-preview
url="/files/audio/1.mp3"
preview-width="120px"
preview-height="80px"
/>
</div>
</template>
<script setup lang="ts">
</script>
PDF预览
自动识别 pdf 格式并渲染 PDF 预览组件。
pdf:
PDF
<template>
<div class="demo-row">
pdf:
<hx-file-preview
url="/files/pdf/1.pdf"
preview-width="120px"
preview-height="80px"
/>
</div>
</template>
<script setup lang="ts">
import { HxFilePreview as FilePreview } from "@whhx/ui"
</script>
邮件预览
自动识别 eml 格式并渲染邮件预览组件。
eml:
加载中...
<template>
<div class="demo-row">
eml:
<hx-file-preview
url="/files/eml/sample.eml"
preview-width="120px"
preview-height="80px"
/>
</div>
</template>
<script setup lang="ts">
</script>
Markdown预览
自动识别 md、markdown 等格式并渲染 Markdown 预览组件。
Markdown
<template>
<div class="demo-row">
<hx-file-preview
url="/files/markdown/sample.md"
preview-width="120px"
preview-height="80px"
/>
</div>
</template>
<script setup lang="ts">
import { HxFilePreview as FilePreview } from "@whhx/ui"
</script>
文本预览
自动识别 txt、json、xml、yaml、csv 等文本格式并渲染文本预览组件。
文本
<template>
<div class="demo-row">
<hx-file-preview
url="/files/text/sample.txt"
preview-width="120px"
preview-height="80px"
/>
</div>
</template>
<script setup lang="ts">
import { HxFilePreview as FilePreview } from "@whhx/ui"
</script>
API
Props
| 参数名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| url | 文件 URL,支持 undefined / null(组件自动展示空状态) | string | undefined | null | - |
| previewWidth | 预览区域宽度 | string | '120px' |
| previewHeight | 预览区域高度 | string | '80px' |
| fallbackThumbnail | 备用缩略图(用于视频等) | string | '' |
支持的文件类型
| 类型 | 扩展名 | 组件 |
|---|---|---|
| 图片 | png, jpg, jpeg, gif, webp, svg, bmp, ico | ImgViewer |
| 视频 | mp4, flv, m3u8, webm, ogg, mov, avi, wmv | VideoViewer |
| 音频 | mp3, wav, ogg, aac, flac, m4a | AudioViewer |
| PdfViewer | ||
| 邮件 | eml | EmlViewer |
| Markdown | md, markdown, mdown, mkdn | MarkdownViewer |
| 文本 | txt, text, log, conf, ini, cfg, config, yaml, yml, json, xml, csv | TextViewer |
| 其他 | - | DefaultViewer |