使用AI一步一步实现若依前端(14)
功能14:使用本地SVG图标库
功能13:侧边栏加入Logo
功能12:折叠/展开侧边栏
功能11:实现面包屑功能
功能10:添加首页菜单项
功能9:退出登录功能
功能8:页面权限控制
功能7:路由全局前置守卫
功能6:动态添加路由记录
功能5:侧边栏菜单动态显示
功能4:首页使用Layout布局
功能3:点击登录按钮实现页面跳转
功能2:静态登录界面
功能1:创建前端项目
前言
在 Vite + Vue3 项目中实现:
- 自动将 SVG 文件转换为可复用的
<symbol>
图标 - 运行时动态加载 SVG 图标
- 通过
<use>
标签高效复用图标
一.操作步骤
1.安装依赖
pnpm add -D vite-plugin-svg-icons
2.Vite 配置(vite.config.js)
import { fileURLToPath, URL } from 'node:url'
import path from 'node:path' // 正确引入 path 模块
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
// https://vite.dev/config/
export default defineConfig({
plugins: [
vue(),
vueDevTools(),
createSvgIconsPlugin({
iconDirs: [path.resolve(process.cwd(), 'src/assets/icons/svg')], // 图标目录
symbolId: 'icon-[dir]-[name]', // 命名规则
inject: 'body-last', // 注入位置
customDomId: '__svg__icons__dom' // DOM ID
})
],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url))
},
},
})
3. 在入口文件引入(main.js)
全局注册自定义SVG组件。
import 'virtual:svg-icons-register'
import SvgIcon from '@/components/SvgIcon/index.vue'
app.component('svg-icon', SvgIcon)
4.组件中使用(MenuItem.vue)
将之前菜单的统一图标,换成svg,根据后端返回的结果,动态显示。
<template>
<div v-if="!item.hidden">
<template v-if="hasChildren">
<el-sub-menu :index="item.path">
<template #title>
<svg-icon :icon-class="item.meta && item.meta.icon"/>
<span>{{ item.meta?.title }}</span>
</template>
<template v-for="child in item.children" :key="child.path">
<MenuItem :item="child" :level="level + 1" :base-path="resolvePath(item.path)" />
</template>
</el-sub-menu>
</template>
<template v-else>
<el-menu-item :index="resolvePath(item.path)">
<svg-icon :icon-class="item.meta && item.meta.icon" />
<template #title>
<span>{{ item.meta?.title }}</span>
</template>
</el-menu-item>
</template>
</div>
</template>
5.自定义SVG组件(SvgIcon.vue)
src\components\SvgIcon\index.vue
<template>
<svg class="svg-icon" aria-hidden="true">
<use :xlink:href="iconName" :fill="color" />
</svg>
</template>
<script setup>
import { computed } from 'vue'
const props = defineProps({
iconClass: {
type: String,
required: true
},
color: {
type: String,
default: ''
}
})
const iconName = computed(() => `#icon-${props.iconClass}`)
</script>
<style scoped lang="scss">
.svg-icon {
width: 1em;
height: 1em;
position: relative;
fill: currentColor;
vertical-align: -2px;
}
</style>
6.修改router/index.js
首页路由记录的图标也换成本地SVG。
{
path: '/',
component: Layout,
redirect: '/index',
meta: { title: '首页', icon: 'dashboard', affix: true },
children: [
{
path: 'index',
component: () => import('@/views/index.vue'),
meta: { title: '首页', icon: 'dashboard', affix: true }
}
]
}
二.功能验证
运行项目,浏览器访问http://localhost:5173/index
三.知识点拓展
1、插件化开发(vite-plugin-svg-icons)
通俗理解:给项目安装一个"SVG图标转换器"
作用:
- 自动扫描指定目录的SVG文件
- 转换为可复用的
<symbol>
标签集合 - 生成虚拟模块供全局使用
类比场景:
就像把散落的工具(单个SVG)整理到工具箱(symbol集合)中,随用随取
2、全局组件注册
实现代码:
// main.js
app.component('svg-icon', SvgIcon)
优势:
- 任何地方无需导入即可使用
<svg-icon>
- 统一管理图标组件
3、动态属性绑定
核心代码:
<svg-icon :icon-class="item.meta?.icon" />
技术点:
:
简写实现动态属性传递- 可选链操作符
?.
防止未定义错误 - 根据路由配置动态显示不同图标
4、计算属性(Computed)
代码片段:
const iconName = computed(() => `#icon-${props.iconClass}`)
作用:
- 自动生成带前缀的图标ID
- 依赖项变化时自动更新
5、样式继承机制
关键CSS:
.svg-icon {
fill: currentColor;
}
特性:
- 自动继承父级文字颜色
- 通过color属性可覆盖
- 实现主题色一键切换
示例:
<div style="color: blue">
<svg-icon icon-class="home" /> <!-- 图标变蓝 -->
</div>
6、路由元信息(Meta)
路由配置:
meta: { icon: 'dashboard' }
应用场景:
- 存储与路由相关的附加信息
- 在导航菜单/面包屑中复用信息
- 实现权限控制的扩展参数
7、组件化设计
组件结构:
SvgIcon.vue
├─ 模板:定义SVG使用方式
├─ 逻辑:处理图标名称
└─ 样式:控制图标外观
设计原则:
- 单一职责:仅处理图标显示
- 开放封闭:通过props接收参数
- 复用性:全项目通用
8、现代前端工程化
涉及工具链:
- Vite:快速构建工具
- PNPM:高效包管理
- PostCSS:样式处理
配置文件示例:
// vite.config.js
createSvgIconsPlugin({
iconDirs: [path.resolve('src/assets/icons')] // 工程路径处理
})
9、响应式图标系统
工作原理:
优势:
- 图标修改无需重新打包
- 按需加载节省资源
- 矢量缩放保证清晰度