nuxt3封装Icon组件

1,051 阅读1分钟

这几天开发公司官网,项目用的是nuxt3,当我想像nuxt2去封装一个icon组件的时候,去看了下官网的文档,但是文档对于如何配置svg-sprite-loader并没有说。 后面总算找到如何去配置,然后就将我这次配置的坑记录一下。

nuxt2配置svg-sprite-loader:

nuxt.config.ts


build: {

    extend (config, ctx) {

      const svgRule = config.module.rules.find(rule => rule.test.test('.svg'))
      svgRule.exclude = [resolve( 'assets/icons/svg')]
      config.module.rules.push({
        test: /.svg$/,
        include: [resolve('assets/icons/svg')],
        use: [{ loader: 'svg-sprite-loader', options: { symbolId: 'icon-[name]' } }]
      })
    }
  }

nuxt2是在nuxt.config.ts文件中配置build属性即可。但是在nuxt3的时候,这个配置方式并不可行。

image.png

刚好,解决的过程中看到这个issue,如果你是使用vite的话,则可以用vite"extend或者vite:extendConfig来配置vite相关的配置项,如果是webpack的话,就是使用webpack:config的方式。

注意:nuxt3项目中是默认使用vite进行打包的,如果是要使用webpack的话,则需要指定vite:false,之前我是通过build的属性来使用,但是那个是使用npm的一个包,那个包会下载失败。

1667013904174.png issue回答原文地址

nuxt3封装icon组件

首先需要下载svg-sprite-loader

npm install svg-sprite-loader

然后配置nuxt.config.ts

 vite: false,
  hooks: {
    'webpack:config': configs => {
      configs.forEach( config => {
        const svgRule = config.module.rules.find( rule => rule.test.test('.svg'))
        svgRule.exclude = [path.resolve(__dirname, 'assets/icons/svg')]
        config.module.rules.push({
          test: /\.svg$/,
          include: [path.resolve(__dirname, 'assets/icons/svg')],
          loader: 'svg-sprite-loader',
          options:{
            symbolId: 'icon-[name]'
          }
        })
      })
    }
  }

plugins下面新建一个文件icons.ts(这个文件类型得为.ts),nuxt3会自动导入这个文件,然后执行。

icon.ts

import SvgIcon from '../components/svgIcon.vue'

export default defineNuxtPlugin(nuxtApp => {
  nuxtApp.vueApp.component('svg-icon', SvgIcon)

  const requireAll = requireContext => {requireContext.keys().map(requireContext)}
  const req = require.context('../assets/icons/svg', false, /\.svg$/)

  requireAll(req)
})

components下面新建svgIcon.vue

<template>
  <svg :class="svgClass" :style="{ width: `${size}px`, height: `${size}px`}">
    <use :xlink:href="`#icon-${name}`" :fill="color" />
  </svg>
</template>

<script setup lang="ts">

const props = withDefaults(defineProps<{
  class?: string
  name: string
  color?: string
  size?: number,
  width?: number,
  height?: number,
}>(), {
  name: '',
  color: '#000',
  size: 24
})

const svgClass = computed( () => [
  'svg-icon',
  props.class
])
</script>


<style scoped>
</style>