vue3加antd Upload 组件来实现文件上传,并结合 Modal 组件实现文件预览功能。

1,020 阅读2分钟

在前端开发中,文件上传和预览功能是常见的需求之一。本文将介绍如何利用 Ant Design Vue 组件库实现文件上传与预览功能。我们将使用 Ant Design Vue 中的 Upload 组件来实现文件上传,并结合 Modal 组件实现文件预览功能。

```
<template>
    <!-- 使用 Ant Design 的 Upload 组件实现文件上传 -->
    <a-upload
     v-model:file-list="fileList"  <!-- 将文件列表与组件双向绑定 -->
    list-type="picture-card"       <!-- 设置文件展示方式为图片卡片形式 -->
    :action="uploadFileParams.url" <!-- 设置上传文件的 URL -->
    :headers="uploadFileParams.headers" <!-- 设置上传文件的请求头信息 -->
    multiple                        <!-- 允许多文件上传 -->
    @preview="handlePreview"        <!-- 预览图片事件 -->
    @change="handleUploadChange">   <!-- 文件上传改变事件 -->
    <plus-outlined />               <!-- 上传按钮图标 -->
    </a-upload>

    <!-- 图片预览弹窗 -->
    <a-modal :visible="previewVisible" :footer="null" @cancel="handleCancel">
        <img alt="example" style="width: 100%" :src="previewImage" /> <!-- 预览图片 -->
    </a-modal>
</template>
```
```
<script setup>

import { ref, reactive, computed } from "vue";
import type { , UploadChangeParam } from "ant-design-vue";
import { uploadFile } from "@/api/base.js";
const formState = reactive<any>({
    fileList: computed(() => {//存储文件列表
        return fileList.value
            .filter((ele: any) => {
                return ele.url;
            })
            .map((ele: any) => {
                return ele.url;
            });
    }),
});
        // 使用 ref 创建响应式数据,用于控制图片预览弹窗的可见性
        const previewVisible = ref(false);
        // 使用 ref 创建响应式数据,存储预览图片的地址
        const previewImage = ref("");
        // 使用 Vue 3 中的 reactive 创建响应式对象,存储上传文件的参数
        const uploadFileParams = uploadFile //上传图片接口

        // 处理文件上传改变时的回调函数
const handleUploadChange = ({ file }: UploadChangeParam) => {
    // 检查文件是否上传完成
    if (file.status === "done") {
        // 遍历文件列表
        fileList.value.forEach((ele: any) => {
            // 如果文件已上传且URL不存在
            if (ele.status === "done" && !ele.url) {
                // 检查响应是否成功
                if (ele.response.code === 0) {
                    // 将URL设置为响应中的数据
                    ele.url = ele.response.data;
                } else {
                    // 若响应失败,则URL为空字符串
                    ele.url = "";
                }
            }
        });
    }
};
        // 处理关闭预览弹窗的回调函数
        const handleCancel = () => {
            previewVisible.value = false; // 将预览弹窗设置为不可见
        };

const isImageUrl = (url: any) => {
    // 定义图片格式的正则表达式
    const imgPattern = /.(jpeg|jpg|gif|png|bmp)$/i;

    // 检查 URL 结尾是否匹配图片格式
    const endsWithImageFormat = imgPattern.test(url);

    // 检查 URL 开头是否是 http:// 或 https://
    const startsWithHttp = url.startsWith("http://") || url.startsWith("https://");

    // 如果 URL 结尾匹配图片格式并且开头是 http:// 或 https://,则返回 true,否则返回 false
    return endsWithImageFormat && startsWithHttp;
};
// 将文件转换为 Base64 格式的函数
// 定义一个函数 getBase64,接受一个文件对象作为参数
const getBase64 = (file) => {
    // 返回一个 Promise 对象,用于处理异步操作
    return new Promise((resolve, reject) => {
        // 创建一个 FileReader 对象
        const reader = new FileReader();
        // 调用 readAsDataURL 方法,读取文件内容,并以 Data URL 的形式返回
        reader.readAsDataURL(file);
        // 读取完成后的回调函数
        reader.onload = () => resolve(reader.result); // 使用 resolve 将结果传递给 Promise 的 then 方法
        // 读取出错时的回调函数
        reader.onerror = (error) => reject(error); // 使用 reject 将错误传递给 Promise 的 catch 方法
    });
};
// 图片
const handlePreview = async (file: any) => {
    if (file.fileType == "png" || isImageUrl(file.url)) {
        if (!file.url && !file.preview) {
            file.preview = (await getBase64(file.originFileObj)) as string;
        }
        previewImage.value = file.url || file.preview;
        previewVisible.value = true;
    } else {
        window.location.href = file.url;
    }
};




};
</script>
```
@/api/base.js 接口
~~~js
```
```
import { axios } from "@/http/axios";
const env = import.meta.env;
```
// 上传文件
// 定义上传文件的配置对象 uploadFile
export const uploadFile = {
    // 上传文件的接口 URL,使用环境变量 VITE_BASE_API_URL 拼接
    url: env.VITE_BASE_API_URL + "/admin-api/infra/file/upload",
    // 请求头部信息,包括租户 ID 和授权 Token
    headers: {
        // 从本地存储获取租户 ID
        "tenant-id": window.localStorage.getItem("tenantId"),
        // 拼接授权 Token,并添加到 Authorization 头部
        Authorization: `Bearer ${window.localStorage.getItem("qyy_token")}`,
    },
};
```