Skip to content

Vue配置svg-sprite-loader以使用svg图标 #2

Description

@fantasticit

svg-sprite-loader在vue中的使用

何为svg sprite

类似于CSS中的雪碧图。将svg整合在一起,呈现的时候根据symbolId来显示特定的图标。

svg sprite与symbol元素

可以这样简单理解,symbol是一个个svg图标,而svg sprite则是symbol的集合,我们可以通过use来指定使用哪一个svg。

在vue中使用

  1. 安装svg-sprite-loader
    执行npm install --save-dev svg-sprite-loader

  2. 修改webpack.base.conf.js
    在rules下添加并修改以下配置:

{
  test: /\.svg$/,
  loader: 'svg-sprite-loader',
  include: [resolve('src/icons')],
  options: {
    symbolId: '[name]'
  }
},
{
  test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
  loader: 'url-loader',
  exclude: [resolve('src/icons')],
  options: {
    limit: 10000,
    name: utils.assetsPath('img/[name].[hash:7].[ext]')
  }
}

配置说明:

  • svg-sprite-loader:
    这里用include: [resolve('src/icons')]来假设项目中所用到svg图标文件在src/icons文件目录下,svg-sprite-loader将只处理这里的文件

  • url-loader:
    这里用xclude: [resolve('src/icons')]来告诉url-loader不要处理src/icons下的图片文件(因为这里已经交给svg-sprite-loader了)

  1. 添加icon组件
    在src/components文件夹下新建文件夹icon,并新建index.vue文件,写入内容如下:
<template>
  <svg :width="width" :height="height">
    <use :xlink:href="iconName"/>
  </svg>
</template>

<script>
export default {
  name: 'Icon',

  props: {
    type: {
      default: 'sad'
    },

    width: {
      default: 50
    },

    height: {
      default: 50
    }
  },

  computed: {
    iconName() {
      return '#' + this.$props.type
    }
  }
}
</script>

<style scoped>
svg {
  fill: currentColor;
  overflow: hidden;
}
</style>
  1. 新建src/icons文件夹
    假如所有的svg文件都放在src/icons/svg文件夹下,那么新建src/icons/index.js文件,写入:
import Vue from 'vue';
import Icon from '@/components/icon';

Vue.component('icon', Icon);

// 导入所有的svg(参照webpack文档: http://webpack.github.io/docs/context.html#dynamic-requires )
~function (requireContext) {
  return requireContext.keys().map(requireContext)
}(require.context('./svg', false, /\.svg$/))

至此,如有不理解,可参照我的src目录结构示意:

├── App.vue
├── assets
│   └── logo.png
├── components
│   └── icon
│       └── index.vue
├── icons
│   ├── index.js
│   └── svg
│       ├── more.svg
│       ├── navicon.svg
│       ├── pause.svg
│       ├── play.svg
│       ├── sad.svg
│       └── wifi.svg
└── main.js
  1. 在main.js引入src/icons/index.js
import Vue from 'vue'
import App from './App'

import './icons/index'

Vue.config.productionTip = false

new Vue({
  el: '#app',
  template: '<App/>',
  components: { App }
})
  1. 如何使用
    以我的App.vue文件举个例子:
<template>
  <div id="app">
    <icon type="play"></icon>
    <icon type="sad"></icon>
    <icon type="more"></icon>
    <icon type="pause"></icon>
    <icon type="wifi"></icon>
  </div>
</template>

<script>
export default {
  name: 'app'
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

效果图

Activity

  1. changed the title [-]在vue中的使用svg图标[/-] [+]vue配置svg-sprite-loader以使用svg图标[/+] on Jan 1, 2018
  2. changed the title [-]vue配置svg-sprite-loader以使用svg图标[/-] [+]Vue配置svg-sprite-loader以使用svg图标[/+] on Jan 1, 2018
  3. porrashuang commented on Jul 9, 2018

    @porrashuang

    手把手教學 寫的非常好!!!!新手入門配置好久終於找到能用的了
    只是不知道是不是我之前遺留的問題 須將iconName() { return '#' + this.$props.type }改成iconName() { return '#icon-' + this.$props.type }

  4. fantasticit commented on Jul 9, 2018

    @fantasticit
    OwnerAuthor

    @kururu002 本文基本写明了每一步步骤,命名什么的可能要看怎么使用的。如果您喜欢这篇文章,欢迎给这个仓库star,权当鼓励。(哈哈)

  5. YuyingZheng commented on Nov 6, 2018

    @YuyingZheng

    以下是我用svg-sprite-loader 插件生成的图片,怎么把<title>avatar</title>删掉呢? 有相关配置选项么?

    <title>avatar</title>
  6. fantasticit commented on Nov 6, 2018

    @fantasticit
    OwnerAuthor

    @yuying-kooboo 没能理解你说的意思,可以看下原文件和生成的文件的内容?

  7. YuyingZheng commented on Nov 6, 2018

    @YuyingZheng

    这是我的原文件:

    <title>avatar</title>

    我希望用这个插件生成后,<title>avatar</title>不要渲染到页面上,如何把这个title去掉呢

    image

  8. fantasticit commented on Nov 6, 2018

    @fantasticit
    OwnerAuthor

    @yuying-kooboo 可以看下 svg 源文件的内容吗?这个应该是你的 svg 源文件内容里就有的 title ,你可以修改源文件试下。

  9. fantasticit commented on Nov 6, 2018

    @fantasticit
    OwnerAuthor

    @yuying-kooboo 用编辑器 打开你的 svg 源文件,svg文件是可以修改的,结构类似 HTML

  10. YuyingZheng commented on Nov 6, 2018

    @YuyingZheng

    Hi, svg源文件是可以修改的,谢谢你了~

  11. fantasticit commented on Nov 6, 2018

    @fantasticit
    OwnerAuthor

    @yuying-kooboo :)

  12. 4 remaining items

  13. fantasticit commented on May 22, 2019

    @fantasticit
    OwnerAuthor

    @brantcao 你可以发一份你的代码(简化后的)给我,我看一下,因为这样在 git issues 里聊的话太费劲了。邮箱:[email protected]

  14. brantcao commented on May 22, 2019

    @brantcao
  15. fantasticit commented on May 22, 2019

    @fantasticit
    OwnerAuthor

    @brantcao 你的 webpack.base.conf.js 配置有问题,url-loader 的配置覆盖了 svg-sprite-loader 的配置,注释掉上面 这个 url-loader 中的 svg 就可以了。

    image

    image

  16. brantcao commented on May 22, 2019

    @brantcao
  17. fantasticit commented on May 22, 2019

    @fantasticit
    OwnerAuthor

    @brantcao 邮箱:[email protected] 。如果可以的话,麻烦帮我点个 star,谢谢。:)

  18. YuyingZheng commented on May 22, 2019

    @YuyingZheng
  19. brantcao commented on May 22, 2019

    @brantcao
  20. fantasticit commented on May 22, 2019

    @fantasticit
    OwnerAuthor

    哈哈,谢谢你们

  21. FredBrock commented on Aug 29, 2019

    @FredBrock

    有没有办吧修改svg组件的颜色呢color ,我添加css {fill:red} 这样貌似无效

  22. fantasticit commented on Aug 30, 2019

    @fantasticit
    OwnerAuthor

    有没有办吧修改svg组件的颜色呢color ,我添加css {fill:red} 这样貌似无效

    image

    你需要结合所使用的 svg 源代码做出相应封装。图中例子,svg 中有 2 个 path,这两个 path 都是可以用 css 调整样式的。同理,封装相应 svg 组件需要定义好 props 使样式生效。

  23. brantcao commented on Sep 12, 2019

    @brantcao
  24. fantasticit commented on Sep 15, 2019

    @fantasticit
    OwnerAuthor

    @brantcao 这个你得自己考虑。我的思路:不同站点分开打包,不同站点打包的 webpack 脚本大部分可以共用,然后在针对不同站点代码补充不同的 webpack 配置,可以看一下 webpack-merge 的文档。

  25. brantcao commented on Sep 15, 2019

    @brantcao
  26. wukaMM commented on May 28, 2020

    @wukaMM

    您好,我也是按上面的配置做的,我的conf文件里面没有使用url-loader, svg除了用svg-sprite-loader处理之外,没有在其他的loader中处理了,但是使用的时候也是空白,0x0,能帮忙看看怎么回事吗

  27. brantcao commented on May 28, 2020

    @brantcao
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions