目录
- 前言
- [1. Demo1](#1. Demo1)
- [2. Demo2](#2. Demo2)
前言
🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF
爬虫神器,无代码爬取,就来:bright.cn
此处的基本知识涉及较少,主要以Demo的形式供大家学习,从实战中触发
本身url是在线链接且是以数组的形式存在
开源项目来源:https://gitee.com/zhijiantianya/ruoyi-vue-pro
1. Demo1
本身一开始以Minio的形式上传,以文件的形式进行命名:

后续用户需要一个个点击才能看到是什么文件
html
<el-form-item label="单证附件" prop="imgPath">
<UploadFile v-model="formData.imgPath" limit="10" />
</el-form-item>
-
把 imgPath 按逗号分割为数组
-
遍历数组,每个链接:
如果是图片(比如后缀是 .jpg、.png 等),就渲染成
<el-image>
如果不是图片,就渲染成带下载链接的文件名
示例的Demo如下:
html
<template>
<div class="file-preview-list">
<div
v-for="(item, index) in fileList"
:key="index"
class="preview-item"
>
<el-image
v-if="isImage(item)"
:src="item"
:preview-src-list="[item]"
fit="cover"
style="width: 100px; height: 100px; margin-right: 10px;"
>
<template #error>
<div style="font-size: 12px; color: #999;">加载失败</div>
</template>
</el-image>
<a
v-else
:href="item"
target="_blank"
style="color: #409EFF; text-decoration: underline;"
>
文件 {{ index + 1 }}
</a>
</div>
</div>
</template>
<script setup>
import { computed } from 'vue';
const props = defineProps({
modelValue: String
});
const fileList = computed(() => {
return props.modelValue
? props.modelValue.split(',').map(item => item.trim())
: [];
});
const isImage = (url) => {
return /\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(url);
};
</script>
<style scoped>
.file-preview-list {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.preview-item {
display: flex;
align-items: center;
}
</style>
组件这样使用:
html
<el-form-item label="单证附件" prop="imgPath">
<UploadFile v-model="formData.imgPath" limit="10" />
<UploadPreview v-model="formData.imgPath" />
</el-form-item>
后续由于图片有些过大,对应以正在加载的形式呈现:
html
<template>
<div class="file-preview-list">
<div
v-for="(item, index) in fileList"
:key="index"
class="preview-item"
>
<el-image
v-if="isImage(item)"
:src="item"
:preview-src-list="[item]"
fit="cover"
style="width: 100px; height: 100px; margin-right: 10px;"
>
<template #placeholder>
<div
style="display: flex; align-items: center; justify-content: center; height: 100%; color: #aaa; font-size: 12px;"
>
正在加载...
</div>
</template>
<template #error>
<div style="font-size: 12px; color: #999;">加载失败</div>
</template>
</el-image>
<a
v-else
:href="item"
target="_blank"
style="color: #409EFF; text-decoration: underline;"
>
文件 {{ index + 1 }}
</a>
</div>
</div>
</template>
<script setup>
import { computed } from 'vue';
const props = defineProps({
modelValue: String
});
const fileList = computed(() => {
return props.modelValue
? props.modelValue.split(',').map(item => item.trim())
: [];
});
const isImage = (url) => {
return /\.(jpg|jpeg|png|gif|bmp|webp)$/i.test(url);
};
</script>
<style scoped>
.file-preview-list {
display: flex;
flex-wrap: wrap;
gap: 10px;
}
.preview-item {
display: flex;
align-items: center;
}
</style>
✅ 推荐结构(用 el-row + 两个 el-col)
原来的结构是把所有内容都放在了一个 el-form-item 里面,这样不太好控制布局
建议改成下面这样:
html
<el-row>
<!-- 左侧:上传控件 -->
<el-col :span="12">
<el-form-item label="单证附件" prop="imgPath">
<UploadFile v-model="formData.imgPath" limit="10" />
</el-form-item>
</el-col>
<el-col :span="12">
<div style="margin-bottom: 8px; font-weight: bold;">附件预览</div>
<UploadPreview v-model="formData.imgPath" />
</el-col>
</el-row>
最终截图如下:

2. Demo2
另外一种呈现的方式如下:
html
<el-table-column label="照片" align="center" prop="imgPath" width="500" fixed="left">
<template #default="{ row }">
<div v-if="row.imgPath && row.imgPath.length > 0" class="damage-images">
<el-image
v-for="(img, index) in row.imgPath"
:key="index"
class="h-80px w-80px"
lazy
:src="img"
:preview-src-list="row.imgPath"
preview-teleported
fit="cover"
/>
</div>
<div v-else class="no-image">无图片</div>
</template>
</el-table-column>