30秒教你学会在vue3(vite)中使用全局svg图标

2,013 阅读1分钟

使用vite搭建vue3时,发现不能使用require.context自动导入模块。可以使用import.meta.globEager来替代,如下:

当时想自己搭建一个vite+vue3+ant-design简易的管理后台,但是发现用vite使用不了require。解决方案如下:

在src全局componnets文件夹下创建一个svg-icon文件夹,并新建一个index.vue文件,文件内容如下:

<template>
    <svg class="svg-icon" aria-hidden="true">
        <use :href="`#${name}`" />
    </svg>
</template>

<script setup>
    defineProps({
        name: {
            type: String,
            required: true
        }
    })
</script>

<style lang="scss" scoped>
    .svg-icon {
        width: 1em;
        height: 1em;
        fill: currentColor;
        overflow: hidden;
    }
</style>

所有svg图片放在src/icons/svg文件夹下。


vue-cli 脚手架:

1、npm包: svg-sprite-loader

加载全部在icons/svg下的文件,并注册为全局组件,src/icons/index.js代码如下:

import { createApp } from 'vue'
import SvgIcon from '@/components/svg-icon/index.vue' // svg component

const requireAll = function(requireContext) {
  return requireContext.keys().map(requireContext)
}

const req = require['context']('./svg', false, /\.svg$/) // 用的是vue-cli-service脚手架,可以使用require

requireAll(req)

export default function(app) {
  app.component('SvgIcon', SvgIcon)
}

写完该文件代码,记得在src/main.js文件引用一下:

import loadSvg from '@/icons'

const app = createApp(App)
// 加载全局 SVG
loadSvg(app)

vue.config.js

module.exports = {
    chainWebpack: config => {
        // svg
        const dir = path.resolve(__dirname, 'src/icons/svg')
        config.module
          .rule('svg-sprite')
          .test(/\.svg$/)
          .include
          .add(dir)
          .end()
          .use('svg-sprite-loader')
          .loader('svg-sprite-loader')
          .options({ extract: false })
          .end()
        config.plugin('svg-sprite')
          .use(require('svg-sprite-loader/plugin')),
          [{ pluginSprite: true }]
        config.module
          .rule('svg')
          .exclude
          .add(dir)
        //
    }
}

vite 搭建的vue3项目:

1、npm包: vite-plugin-svg-icons

加载全部在icons/svg下的文件,并注册为全局组件,src/icons/index.js代码改成:

import { createApp } from 'vue'
import SvgIcon from '@/components/svg-icon/index.vue' // svg component

const requireAll = function (requireContext) {
  return Object.values(requireContext);
};

const req = import.meta.globEager("./svg/*.svg");

requireAll(req)

export default function(app) {
  app.component('SvgIcon', SvgIcon)
}

同样需要全局main.js引入一下,代码同上

vite.config.js

import { createSvgIconsPlugin } from 'vite-plugin-svg-icons'

export default defineConfig({
  plugins: [
    vue(),
    createSvgIconsPlugin({
      iconDirs: [path.resolve(process.cwd(), 'src/icons/svg')],
      symbolId: '[name]'
    })
  ],
 })

接着就可以在项目中使用icon了,

<svg-icon name="dashboard" />

截屏2022-04-19下午1.48.23.png