Nuxt3 動態加載圖片,別再搞錯 assets 跟 public!
做 Nuxt3 專案你一定遇過這個問題:「我要根據 API 傳回來的檔名顯示圖檔,那圖片到底該放 assets 還是 public?」
老實說,這問題我自己也被搞過,網路上的說法一堆,還有很多超複雜的解釋。這篇就直接白話搞定,給你結論跟範例。
assets 跟 public 到底差在哪?
先講結論:
- 要用字串拼
src路徑? → 全部放 public - 要給 vite/webpack 處理 hash? → 放 assets,但只能靜態 import,用變數就掰掰
簡單來說:
public= 用 URL 直接拿圖,怎麼拼都行assets= 只能靜態 import(vite/webpack 會 hash 路徑),不能用字串拼
為什麼 public 比 assets 靈活?
public 下的東西打包時完全不會動,名字、路徑都不會被處理。所以你怎麼拼 URL 都能抓到圖(無論 dev/prod 都一樣):
<template>
<img :src="`/images/products/${imageName}.webp`" alt="">
</template>
<script setup>
const imageName = 'product-001'
</script>
Copy!
這做法超簡單,而且不用在意 Vite/Webpack 會不會幫你 hash 路徑,反正就是長什麼名就給你什麼名。
assets 只能給靜態 import
如果你硬要用 assets 裡的圖,只能這樣:
import dog from '~/assets/images/dog.png'
Copy!
或者在 component 直接:
<img src="~/assets/images/dog.png" />
Copy!
vite/webpack 會自動幫你加 hash,路徑變成 /assets/dog.abcd1234.png。
但是!你不能這樣搞:
const imgPath = `~/assets/images/${imgName}.png` // 掰掰,這抓不到
Copy!
因為 build 完根本沒這個檔名,webpack 不知道你要什麼。
選擇題
- 想動態換圖?→ 放 public
- 圖片名不變、想被 hash 處理?→ 放 assets
常見問題
Q: API 傳一堆檔名,怎麼顯示圖?
A: 圖全部丟 public,直接拼 URL
Q: 靜態圖只在 component 用?
A: assets 隨你,vite 會 hash,自然幫你優化
Q: public 圖片路徑 dev/prod 會變嗎?
A: 不會。你看到 /images/foo.png 就是 /images/foo.png,不用想太多
最後
遇到圖片路徑有鬼,十之八九就是 assets 跟 public 放錯了,檢查一下就對了。
