Nuxt3 動態加載圖片(到底該放哪裡?)

> Nuxt3 動態加載圖片

Nuxt3 動態加載圖片(到底該放哪裡?)

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>

這做法超簡單,而且不用在意 Vite/Webpack 會不會幫你 hash 路徑,反正就是長什麼名就給你什麼名。

assets 只能給靜態 import

如果你硬要用 assets 裡的圖,只能這樣:

import dog from '~/assets/images/dog.png'

或者在 component 直接:

<img src="~/assets/images/dog.png" />

vite/webpack 會自動幫你加 hash,路徑變成 /assets/dog.abcd1234.png。

但是!你不能這樣搞:

const imgPath = `~/assets/images/${imgName}.png` // 掰掰,這抓不到

因為 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 放錯了,檢查一下就對了。

Ref