目錄
- 前言
- 1. 引用 public/ 目錄
- 2. assets/ 目錄
- 3. 遠程服務器
- 4. Vue Router 動態訪問
- 5. 總結
- 6. 擴展(圖片不顯示)
前言
🤟 找工作,來萬碼優才:👉 #小程序://萬碼優才/r6rqmzDaXpYkJZF
在 Vue 開發中,圖片的引用方式主要取決于圖片存放的位置,常見的存放方式包括:
- 存放在 public/ 目錄
- 存放在 assets/ 目錄
- 存放在遠程服務器
- 動態拼接圖片路徑
本文將詳細分析這些方式的區別,并提供完整的代碼示例和注釋
1. 引用 public/ 目錄
public/ 目錄下的文件會被 Vue 直接映射到項目的根路徑 /,無需 Webpack 處理,適用于:
- 不會被打包處理的靜態資源
- 圖片 URL 確定,不依賴 Webpack 解析
? 正確寫法
<template><div><!-- 直接從 public 目錄訪問圖片 --><img src="/manufacturing.png" alt="Manufacturing Image" /></div>
</template>
? 錯誤寫法
<template><div><!-- public 目錄不需要 public/ 前綴 --><img src="/public/manufacturing.png" alt="Error Image" /></div>
</template>
說明: public/ 目錄的內容會被 Vue 直接映射到根路徑 /,所以訪問 /public/xxx.png 是錯誤的
截圖如下:
2. assets/ 目錄
適用場景
assets/ 目錄下的圖片會被 Vue 通過 Webpack 進行打包,適用于:
- 存放在 src/assets/ 目錄
- 需要 Webpack 處理,如哈希命名
- 圖片路徑動態變化
? 使用 import 方式
<script setup>
import imageUrl from '@/assets/images/manufacturing.png'
</script><template><div><img :src="imageUrl" alt="Manufacturing Image" /></div>
</template>
說明:
import 方式會將圖片路徑解析為 Webpack 處理的 URL
適用于靜態導入,但不適用于動態路徑拼接
? 使用 new URL() 方式
<script setup>
const imageSrc = new URL('@/assets/images/manufacturing.png', import.meta.url).href
</script><template><div><img :src="imageSrc" alt="Manufacturing Image" /></div>
</template>
說明:
new URL() 適用于 assets 目錄,支持動態路徑處理
3. 遠程服務器
適用場景
- 圖片存放在 CDN 或外部服務器
- 不需要 Webpack 處理
<template><div><img src="https://example.com/images/manufacturing.png" alt="Remote Image" /></div>
</template>
說明:
直接使用絕對 URL 訪問遠程圖片,無需 Vue 處理
4. Vue Router 動態訪問
圖片名稱與路由路徑相關聯,可以使用 computed 計算屬性自動生成圖片路徑
<template><div><img :src="imageSrc" alt="Dynamic Page Image" /></div>
</template><script setup>
import { useRoute } from 'vue-router'
import { computed } from 'vue'const route = useRoute()// 計算 public 目錄下的圖片路徑
const imageSrc = computed(() => {const sanitizedPath = route.path.replace(/^\//, '') // 移除開頭的 `/`return `/${sanitizedPath}.png` // 訪問 public 目錄
})
</script>
假設 public 目錄結構如下:
public/
├── home.png
├── about.png
├── contact.png
訪問 /home 時,圖片路徑為:
<img src="/home.png" />
動態路由的方式有所差異:
<template><div><img :src="imageSrc" alt="Dynamic Page Image" /></div>
</template><script setup>
import { useRoute } from 'vue-router'
import { computed } from 'vue'const route = useRoute()// 計算 public 目錄下的圖片路徑
const imageSrc = computed(() => {const sanitizedPath = route.path.replace(/^\//, '') // 移除開頭的 `/`const lastSegment = sanitizedPath.split('/').pop() // 獲取最后的路徑部分return `/${lastSegment}.png` // 訪問 public 目錄
})
</script>
截圖如下:
5. 總結
總的來說:
存放位置 | 適用場景 | 訪問方式 | 代碼示例 |
---|---|---|---|
public/ | 直接訪問,無需 Webpack 處理 | /filename.png | <img src="/manufacturing.png" /> |
assets/ | 需要 Webpack 處理 | import 或 new URL() | import img from '@/assets/image.png' |
遠程服務器 | 圖片在外部服務器/CDN | 絕對 URL | <img src="https://example.com/image.png" /> |
動態路由 | 根據 Vue Router | 動態生成圖片路徑 | computed 計算屬性 :src=“computedPath” |
最佳實踐:
- public/ 目錄適用于靜態資源,直接使用 /filename.png 訪問
- assets/ 目錄適用于 Webpack 處理,使用 import 或 new URL()
- 外部圖片直接使用絕對 URL
- 動態圖片路徑可結合 Vue Router 計算生成
6. 擴展(圖片不顯示)
圖片無法顯示通常是路徑錯誤、資源未正確加載或 Webpack/Vite 處理導致的問題
圖片不顯示的常見原因
在 Vue 3 + Vite(或 Webpack)項目中,圖片可能無法顯示的常見原因包括:
- 路徑錯誤:引用 public/ 目錄時仍加 public/ 前綴
- 資源未正確加載:如 src/assets/ 目錄下的圖片未被 Webpack 處理
- 動態路徑問題:使用 computed 計算屬性拼接路徑時錯誤
- Webpack 處理方式:assets/ 目錄下的圖片會被 Webpack 處理,不能直接訪問
- 圖片格式或大小問題:瀏覽器不支持的圖片格式或圖片損壞
路徑錯誤這個要點此處著重分析下
詳細分析下為何要放在public等路徑下!
public/ 目錄的映射機制
在 Vue 項目結構中:
my-project/
├── public/
│ ├── manufacturing.png
│ ├── images/
│ │ ├── factory.png
├── src/
│ ├── views/
│ │ ├── Industry.vue
│ ├── assets/
│ │ ├── example.png
│ ├── App.vue
public/manufacturing.png 在構建后會被 Vue 直接映射到:/manufacturing.png
public/images/factory.png 在構建后會變成:/images/factory.png
src/assets/example.png 則會被 Webpack 處理,并生成動態路徑(如 /assets/example.abcdef.png)
如何證明 public/ 目錄直接映射到根路徑 /?
可以打開 http://localhost:5173/manufacturing.png,如果 manufacturing.png 直接顯示,則說明它已經被映射到根目錄 /,而不需要 /public/manufacturing.png
對比 public/ 和 src/assets/
存放目錄 | 是否被 Webpack 處理 | 訪問方式 | 適用場景 |
---|---|---|---|
public/ | ? | 否 | /filename.png |
src/assets/ | ? | 是 | import 或 new URL() |
? 使用 public/ 目錄
<template><div><img src="/manufacturing.png" alt="Manufacturing Image" /></div>
</template>
? 使用 src/assets/ 目錄
<script setup>
import imgUrl from '@/assets/example.png'
</script><template><div><img :src="imgUrl" alt="Example Image" /></div>
</template>