在Vue项目中使用svg标签

281 阅读1分钟

在vue中使用svg标签:需要先安装 svg-sprite-loader

使用npm或yarn安装
npm install svg-sprite-loader -D
yarn add --dev svg-sprite-loader -D

svg-sprite-loader作用:把svg变成symbol标签,把symbol标签放到svg标签里面,使用svg标签时,使用use标签

配置文件,在.vue.d.ts中加入下面代码

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

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

const path = require('path')                                  //引入path模块
module.exports = {
  lintOnSave: false,
  chainWebpack: config =>{
    const dir = path.resolve(__dirname, 'src/assets/icons')   //确定icons所在目录
    config.module                //config是vue封装webpack之后的API暴露给我们的对象
      .rule('svg-sprite')        //添加规则
      .test(/\.svg$/)            //如果文件匹配了正则(以.svg为结尾),就用这个规则
      .include.add(dir).end()    //只包含 icons目录,其它目录不管
      .use('svg-sprite-loader').loader('svg-sprite-loader').options({extract:false}).end()        //使用svg-sprite-loade
      config.plugin('svg-sprite').use(require('svg-sprite-loader/plugin'),[{plainSprite: true}])  //配置插件svg-sprite
      config.module.rule('svg').exclude.add(dir)       //其它svg-loader 排除 icons
  }
}

有可能require会报错:require statement not part of an import statement

.eslintrc.js中的rules里添加下面代码

 rules: {
    '@typescript-eslint/no-var-requires': 0
  }

使用svg(svg + use标签)

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

需要引用svg
<script lang="ts">
    import x from '@/assets/icons/label.svg';
    export default {
    name:'Nav'
  }
</script>

每次使用svg都需要从icons里引用,太麻烦,封装Icon组件 Icon.vue

<template>
  <svg @click="$emit('click', $event)" class="icon">   //给svg添加点击事件
    <use :xlink:href="'#'+name"/>                      //use接收外部传进来的name(icon名)
  </svg>
</template>

<script lang="ts">
  const importAll = (requireContext: __WebpackModuleApi.RequireContext) => requireContext.keys().forEach(requireContext);
  try{importAll(require.context('../assets/icons', true, /\.svg$/));}catch(error){console.log(error);}
//声明importAll方法,它接受一个requireContext对象,类型是__WebpackModuleApi.RequireContext
//使用这个对象,调用它的keys,然后forEach进行(requireContext)
//使用try catch防止,如果出问题就把问题打出来,代码不中断
//require.context指定去哪个目录搜索

  export default {
    props: ['name'],
    name: 'Icon'
  };
</script>

<style lang="scss" scoped>
//设置icon的默认样式
  .icon {
    width: 1em; height: 1em;
    vertical-align: -0.15em;
    fill: currentColor;
    overflow: hidden;
  }
</style>

使用svg,十分简洁

<Icon name="xxx"/>