目录结构
src/
├── assets/
│ └── icons/
│ └── logo.png # 图标文件
└── components/
└── Demo.vue
1. 模板内直接使用(最常用)
相对路径(推荐,单文件组件内)
<template>
<!-- img 标签 -->
<img src="@/assets/icons/logo.png" alt="图标" />
<!-- 背景图 / 行内样式 -->
<div
:style="{ backgroundImage: 'url(@/assets/icons/logo.png)' }"
class="icon-box"
></div>
</template>
<style scoped>
.icon-box {
width: 40px;
height: 40px;
background-size: contain;
background-repeat: no-repeat;
}
</style>
@在 Vite 中默认映射到src/,无需额外配置。
2. JS/TS 中导入后使用
动态图标、循环渲染必用
Vite 中动态字符串路径无法直接识别,必须先 import 引入资源。
<template>
<img :src="logoImg" alt="图标" />
<!-- 动态切换图标 -->
<img :src="currentIcon" alt="动态图标" />
</template>
<script setup>
// 1. 静态导入单个图标
import logoImg from '@/assets/icons/logo.png'
// 2. 多图标、动态切换
import icon1 from '@/assets/icons/icon1.png'
import icon2 from '@/assets/icons/icon2.png'
const currentIcon = icon1
</script>
3. 批量导入 assets 图标
大量图标场景
使用 import.meta.glob 批量引入,Vite 专属 API:
<template>
<div v-for="(item, name) in iconList" :key="name">
<img :src="item" alt="" />
</div>
</template>
<script setup>
// 批量匹配 assets/icons 下所有图片
const iconList = import.meta.glob('@/assets/icons/*.png', {
eager: true, // 立即加载(而非懒加载)
import: 'default'
})
</script>
常见问题 & 避坑
路径报错、图片不显示
- 不要写
../assets,统一用@/assets - 动态拼接字符串
url('@/assets/'+name)无效,必须先import
- 不要写
Vite 静态资源规则
- 放在
src/assets:编译时打包,路径需import/@ - 放在
public文件夹:原样复制,直接写/图标.png,不用@
- 放在
样式 scoped 导致 svg 样式不生效
svg 作为组件使用时,可移除scoped或使用:deep()。