Ant-Design-Vue 圖片上傳
功能演示
我們要實現的功能如下,有兩個按鈕,點擊第一個按鈕選擇文件,選擇文件后點擊第二個按鈕上傳到服務器。
功能需求:
-
只允許上傳
png、jpg/jpeg格式的圖片 -
沒有上傳圖片時顯示占位圖
-
選擇完圖片后在頁面中渲染出來




構建頁面
template
<template>
<div>
<div>
<!-- 選擇圖片后展示待上傳的圖片 -->
<img v-if="base64img" :src="base64img" />
<!-- ↓ 沒有選擇時顯示占位圖 -->
<img v-else="base64img" src="@/assets/placeholderImg.png" />
</div>
<!-- 限制最大待上傳的文件數量為 1 -->
<!-- 添加選擇文件后的回調和移除待上傳文件的回調 -->
<a-upload :before-upload="beforeUpload" :max-count="1" @remove="handleRemove">
<a-button>
<upload-outlined></upload-outlined>
Select File
</a-button>
</a-upload>
<!-- 點擊上傳按鈕 -->
<a-button @click="triggerUpload" :loading="btnLoading">上傳</a-button>
</div>
邏輯部分
TypeScript
import { UploadOutlined } from '@ant-design/icons-vue'
import fruitApi from "@/api/fruitApi";
import {ref} from "vue";
import {Upload} from "ant-design-vue";
import {Notice} from "@/utils/interfaces";
const fileList = ref();
// ↑ 待上傳文件列表 (其實里面也就能放一個文件)
const base64img = ref();
// ↑ 我們在頁面中顯示待上傳的圖片的原理是
// 將所選擇的本地圖片轉換為 Base64 編碼
// 之后讓圖片的 src = base64img 來實現的
// 所以 base64img 就是一個儲存圖片編碼的字符串
const btnLoading = ref<boolean>(false);
// ↑ 上傳按鈕的 loading 狀態
// 在點擊上傳 至 獲取服務器回調的時間內 按鈕不可用
/**
* 對圖片編碼的函數
*/
function getBase64(img: Blob, callback: (base64Url: string) => void) {
const reader = new FileReader();
reader.addEventListener('load', () => callback(<string>reader.result));
// ↑ 監聽 reader 的 load 事件,觸發時執行回調函數
// 回調函數的作用就是將圖片編碼的base64字符串傳給 base64img
reader.readAsDataURL(img);
}
/**
* andv 上傳文件的回調
* 返回 false 則不會上傳文件,而是由我們手動上傳
* 返回 Upload.LIST_IGNORE 會取消將文件添加至待上傳列表
* @param file 所選擇的文件
*/
function beforeUpload(file: any) {
console.log(file);
// 判斷文件是否為圖片格式
const isImg = (file.type === 'image/jpeg' || file.type === 'image/png');
// 如果文件不是圖片格式則禁止上傳
if (!isImg) {
Notice.error("只能上傳 jpeg/jpg/png 格式的文件!");
// ↑ Notice.error 是我自己寫的 Notice 類的一個靜態函數
// 用的是 antdv 的 Notifiacation
return Upload.LIST_IGNORE;
}
fileList.value = file;
// ↓ 獲取所需要上傳圖片的 Base64 編碼
getBase64(fileList.value, (cb_img: string) => {
// 將獲取到的所要上傳圖片的 Base64 編碼渲染到圖片上
base64img.value = cb_img;
})
return false;
}
/**
* 點擊上傳按鈕的回調
*/
function triggerUpload() {
const formData = new FormData();
// 對文件列表 判空
if (fileList.value != null) {
formData.append("file", fileList.value as any);
} else {
Notice.error("文件不能為空!")
return Upload.LIST_IGNORE;
}
// ↓ 在上傳過程中,按鈕為 loading 狀態
btnLoading.value = true;
// 請求上傳接口
fruitApi({
method: 'put',
url: 'api/upload',
data: formData
})
.then((resp: any) => {
console.log(resp);
if (resp.code === 1) {
Notice.success(<string>resp.data);
changeUploadItemColor("#49aa19");
} else {
Notice.error("上傳失敗~");
changeUploadItemColor("#ff4d4f");
// ↑ 下面會提到這個函數
}
btnLoading.value = false;
})
.catch((err) => {
console.log(err);
Notice.error("發生了錯誤~");
btnLoading.value = false;
changeUploadItemColor("#ff4d4f");
})
}
/**
* 待上傳圖片被刪除的回調
*/
function handleRemove() {
fileList.value = null;
// ↑ 置空待上傳文件列表
base64img.value = null;
// ↑ 顯示默認占位圖
}
/**
* 上傳圖片成功或失敗后 list 變色的函數
*/
type uploadItemColor = "#49aa19" | "#ff4d4f";
// ↑ 兩個顏色 綠 和 紅
function changeUploadItemColor(color: uploadItemColor) {
const uploadListItem = document.querySelector(".ant-upload-list-item-name");
// ↑ 類名是 antdv 規定的,選擇這個類名即可
(uploadListItem as any).style.color = color;
// ↑ 使item文字變色
}
這次真的是把
TypeScript寫成了anyScript,中間不知道用了多少的類型斷言和:any??
End
開頭已經展示過頁面效果啦,就不再測試了 ??

浙公網安備 33010602011771號