如何在vue内引入svg

116 阅读1分钟

问题来源

最近使用了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'/>