问题来源
最近使用了VUE做单页面项目,要引入SVG。webpack引入svg的方法说实话很简单,但是vue直接给你提供的是vue.config.js。vue.config.js是vue项目的配置文件,专用于vue项目。通过vue.config.js中常用功能的配置,简化了配置工作,当然如果需要更专业的配置工作,两者在vue项目中是可以并存的。但是这是个简单的移动端小项目,正好可以看看vue.config.js如何引入loader。
答案
去网上查询了很多资料,最后得到以下的处理方式。
const path = require('path')
module.exports = {
lintOnSave: false,
chainWebpack: config => {
const dir = path.resolve(__dirname, 'src/assets/icons')
config.module
.rule('svg-sprite')
.test(/.svg$/)
.include.add(dir).end()
.use('svg-sprite-loader').loader('svg-sprite-loader').options({extract: false}).end()
.use('svgo-loader').loader('svgo-loader')
.tap(options => ({...options, plugins: [{removeAttrs: {attrs: 'fill'}}]})).end()
config.plugin('svg-sprite').use(require('svg-sprite-loader/plugin'), [{plainSprite: true}])
config.module.rule('svg').exclude.add(dir)
}
}
代码很清晰地展示了chainWebpack: config => {}是最终和webpack的config会链接在一起。
接着,创建一个Icon的Vue组件。
<template>
<svg class="svg-icon">
<use :xlink:href="'#' + name"/>
</svg>
</template>
<script lang="ts">
// eslint-disable-next-line no-undef
let importAll = (requireContext: __WebpackModuleApi.RequireContext) => {requireContext.keys().forEach(requireContext);};
try {
importAll(require.context('../assets/icons', true, /.svg$/));
} catch (error) {
console.log(error);
}
export default {
props: ['name'],
name: 'Icon'
};
</script>
这里可以看到,我们声明了一个方法叫importAll,参数是requireContext,类型是__WebpackModuleApi.RequireContext,然后进行一个回调。
这个组件接着在main.ts里声明,就可以使用了。即可以以<Icon name='xxxx'/>的形式使用。也可动态绑定成
<Icon :name='xxxx'/>。