iter(g173): 上传图片显示缩略图

This commit is contained in:
HIsheR
2026-10-26 16:20:30 +08:00
parent 2c17696cc5
commit ea4e781bd4
5 changed files with 27 additions and 4 deletions
+11
View File
@@ -36,13 +36,24 @@ export function upload(props: UploadProps): HTMLElement {
sync();
};
// —— 图片缩略图:对象 URL 按 File 缓存,文件离场即释放(否则整页存活期都在泄漏) ——
const urls = new Map<File, string>();
const thumbOf = (file: File): HTMLElement | null => {
if (!file.type.startsWith('image/')) return null; // 卫语句:非图片不缩略,只给文件名
let url = urls.get(file);
if (!url) { url = URL.createObjectURL(file); urls.set(file, url); }
return h('img', { class: 'ua-upload-thumb', src: url, alt: '', loading: 'lazy' });
};
/*** 重绘清单并回传(选择/拖拽/移除都走这里,保证单一出口) ***/
const sync = (tip = '') => {
for (const [file, url] of urls) if (!files.includes(file)) { URL.revokeObjectURL(url); urls.delete(file); } // 已离场的文件先释放
listEl.replaceChildren(
...files.map((file, i) =>
h(
'div',
{ class: 'ua-upload-item' },
thumbOf(file),
h('span', { class: 'ua-upload-name' }, file.name),
h('span', { class: 'ua-upload-size' }, size(file.size)),
h('button', { type: 'button', class: 'ua-upload-remove', 'aria-label': `移除 ${file.name}`, onclick: () => remove(i) }, '×'),
+2 -1
View File
@@ -2303,7 +2303,8 @@
"把 upload 放进表单,accept 限定类型、multiple 允许多选",
"需要拦体积就给 maxSize(字节),限制数量给 maxCount",
"被拒的文件不会进清单,原因显示在下方提示行(拖拽与点选走同一套校验)",
"onChange 拿到的 File[] 是副本,自行发请求上传(组件不内置网络层)"
"onChange 拿到的 File[] 是副本,自行发请求上传(组件不内置网络层)",
"选中的图片会带 28px 缩略图(对象 URL,随文件离场即 revoke,不会泄漏);非图片只显示文件名与体积,点 × 移除"
]
},
{
+9
View File
@@ -2700,6 +2700,15 @@ button.ua-step-dot:hover {
border-radius: var(--ua-radius-sm);
font-size: var(--ua-font-size-sm);
}
.ua-upload-thumb {
width: 28px;
height: 28px;
object-fit: cover;
border: 1px solid var(--ua-color-border);
border-radius: var(--ua-radius-sm);
background: var(--ua-color-surface);
flex: 0 0 auto;
}
.ua-upload-name {
flex: 1;
min-width: 0;