这几天开发公司官网,项目用的是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的时候,这个配置方式并不可行。
刚好,解决的过程中看到这个issue,如果你是使用vite的话,则可以用vite"extend或者vite:extendConfig来配置vite相关的配置项,如果是webpack的话,就是使用webpack:config的方式。
注意:nuxt3项目中是默认使用vite进行打包的,如果是要使用webpack的话,则需要指定vite:false,之前我是通过build的属性来使用,但是那个是使用npm的一个包,那个包会下载失败。
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>