SVG的引入及坑

作者: 浪味仙儿啊 | 来源:发表于2020-06-10 16:34 被阅读0次

    在Vue项目中使用需要先安装svg-sprite-loader

    npm install svg-sprite-loader -D
    或
    yarn add --dev svg-sprite-loader -D
    

    先在.d.ts文件中加入两行代码,如下

    declare module "*.svg"{
      const content: string;
      export default content;
    }
    

    在vue.config.js中配置以下代码

    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()
           config.plugin('svg-sprite').use(require('svg-sprite-loader/plugin'), [{plainSprite: true}])
           config.module.rule('svg').exclude.add(dir)
       }
    };
    

    然后在需要使用到svg的文件中template部分写以下代码

    <template>
        <svg>
             <use xlink:href="#xxx"/>
        </svg>
    </template>
    

    在ts部分写以下代码

    <script lang="ts">
        import x from '@/assets/icons/label.svg';
        console.log(x)//这里使用log是因为,引入svg如果没有用到,那么用import就会被Treeshaking,下面会用require。
        export default {
        name:'Nav'
      }
    </script>
    

    svg-sprite-loader会把svg变成symbol,symbol对应的id为label,并在symbol外套一个svg,在body里生成。

    如要使用多个svg,那在文件里添加几次svg,使用几次use,在ts里import几次即可,但这样很麻烦,可以引入一个目录,把ts里的代码改成如下

    <script lang="ts">
    
      let importAll = (requireContext: __WebpackModuleApi.RequireContext) => requireContext.keys().forEach(requireContext);
      try {
        importAll(require.context('../assets/icons', true, /\.svg$/));//使用require
      } catch (error) {
        console.log(error);
      }
      export default {
        name: 'Icon'
      };
    </script>
    

    SVG的坑

    如果svg里自带颜色fill="red",那么在外面怎么修改都无法改变颜色,这时可以把svg中的fill删掉,但如果有十多二十个,甚至上百个svg,删起来就很麻烦。
    另一个办法就是安装svgo-loader(yarn add --dev svgo-loader)并在vue.config.js的config.nodule下添加两句代码

    config.module
                .use('svgo-loader').loader('svgo-loader')
                .tap(options=>({...options,plugins:[{removeAttrs:{attrs:'fill'}}]})).end();
    

    这会自动去掉svg中的fill属性

    在React项目中同样要做这些操作

    但是在安装svg-sprite-loader和svgo-loader之前要先yarn eject,生成webpack.config.js,之后在该文件module→rules→oneOf中添加以下代码

    {
      test: /\.svg$/,
      use: [
        { loader: 'svg-sprite-loader', options: {} },
        { loader: 'svgo-loader', options: {} }
      ]
    }
    

    同样引入svg也要添加下面两行代码

      let importAll = (requireContext: __WebpackModuleApi.RequireContext) => requireContext.keys().forEach(requireContext);
      try {importAll(require.context('icons', true, /\.svg$/));} catch (error) {console.log(error);}
    

    这时 __WebpackModuleApi和require会报错,安装@types/webpack-env(yarn add --dev @types/webpack-env)错误就会消除

    相关文章

      网友评论

        本文标题:SVG的引入及坑

        本文链接:https://www.haomeiwen.com/subject/jpsetktx.html