在vue项目中,我们除了使用组件库(ant-design-vue element-ui)的icon以外,还有我们自己自定义的图标,对于自定义图标的话,我们暂时还缺少显示的方式。所以说我们需要一个自定义的组件,来显示我们自定义的 svg 图标。

我们用的iconfont里的图标 有的会用线上的图标,直接调用,但是会出现 如果线上服务器崩了,我们的图标是不是也都不显示了,这里我们一般都是把图标下载下来。

这里目前推荐下载svg格式的图标。

1,首先去官网下载自己需要的icon图标,注意是svg格式的  iconfont-阿里巴巴矢量图标库

2,将下载下来的图标放置到项目中专门放图片的文件夹中,可以单独放一个svg目录中

一、安装vite-plugin-svg-icons

此处还需要安装下fast-glob相关依赖,不然vite运行时会报Cannot find module 'fast-glob’的错误,

如果npm安装的就这么安装

npm i vite-plugin-svg-icons -D
npm i fast-glob@3.x -D

如果是yarn下载环境的,使用ant组件库的项目,就要这么安装,这里fast-glob@3.x用npm安装,亲测用yarn安装就报错,npm安装就可以

yarn add vite-plugin-svg-icons -D
npm i fast-glob@3.x -D

二、在src/components/svgIcon下新建组件svgIcon.vue

<template>
  <svg aria-hidden="true" :class="svgClass">
    <use :xlink:href="symbolId" :fill="props.color" />
  </svg>
</template>

<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
  name: 'svg-icon'
})
</script>
<script lang="ts" setup>
import { computed } from 'vue'
const props = defineProps({
  prefix: {
    type: String,
    default: 'icon'
  },
  name: {
    type: String,
    required: true
  },
  color: {
    type: String,
    default: '#333'
  },
  className: {
    type: String,
    default: ''
  }
})
const symbolId = computed(() => `#${props.prefix}-${props.name}`)
const svgClass = computed(() => {
  if (props.className) {
    return `svg-icon ${props.className}`
  }
  return 'svg-icon'
})

</script>

<style>
.svg-icon {
  width: 1em;
  height: 1em;
  vertical-align: -0.1em;
  /* 因icon大小被设置为和字体大小一致,而span等标签的下边缘会和字体的基线对齐,故需设置一个往下的偏移比例,来纠正视觉上的未对齐效果 */
  fill: currentColor;
  /* 定义元素的颜色,currentColor是一个变量,这个变量的值就表示当前元素的color值,如果当前元素未设置color值,则从父元素继承 */
  overflow: hidden;
}
</style>

三、在main.ts全局注册组件

import { createApp } from 'vue'
import App from './App.vue'
import router from '@/router'
import { store, key } from '@/store'
import 'virtual:svg-icons-register' // 引入注册脚本
import SvgIcon from '@/components/svgIcon/index.vue' // 引入组件
const app = createApp(App)
app.component('svg-icon', SvgIcon)
app.use(router).use(store, key).mount('#app')

四、vite.config.ts 中的配置插件

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'
import path from "path"

export default defineConfig({
   plugins: [
    vue(),
    createSvgIconsPlugin({
      // 指定需要缓存的图标文件夹
      iconDirs:[path.resolve(process.cwd(),'src/assets/icons')],
      // 指定symbolld格式
      symbolId: 'icon-[dir]-[name]' 
    })
  ],
})

五、在页面中使用

<svg-icon name="del" className="my" color="green" />

name为svg文件名称,比如调用 del.svg,这里name就为del,className则为样式调用,这里的my的样式可以写在调用该组件的页面中,color控制颜色

六、在后台管理页面中,控制svg图标显示

在后台管理中,有的菜单需要不同的图标,但是在项目中是统一循环出来的,不好一个一个手动设定,比如这样的

 不同的菜单不同的图标,这个时候可以在添加菜单的时候,加上一个字段button名称字段,填写svg名称,在调用菜单的时候,返回这个字段,然后在<svg-icon name="del" className="my" color="green" />中调用

 

<a-sub-menu :key="menuInfo.name" v-if="!menuInfo.hidden">
        <template #icon v-if="menuInfo.meta" >
          <svg-icon v-if="menuInfo.meta.icon" :name="menuInfo.meta.icon"  className="menuIcon" /> 
          <svg-icon v-else name="type"  className="menuIcon" />
        </template>
        <template #title>{{ menuInfo.meta.title || menuInfo.title }}</template>
        <template v-for="item1 in menuInfo.children" :key="'nav' + item1.name" >
          <nav-menu :menu-info="item1"  />
        </template>
    </a-sub-menu>

这里就是项目中的部分代码,svg的name就是调用的后台传过来的值,通过这个值来显示不同的图标

Logo

前往低代码交流专区

更多推荐