5

I want to import multiple svg's in one vue component. The documentation says I Have to import each one of them, but how can I import multiple svgs in a much shorter and cleaner way?

vue-svg-loader documentation: https://vue-svg-loader.js.org/

<script>
import Info from "@/assets/svgs/info.svg";
import Help from "@/assets/svgs/help.svg";
import Close from "@/assets/svgs/close.svg";
// etc. pp.

export default {
  components: {
    Info,
    Help,
    Close
  }
</script>

What happens if I got over one hundred svg's I want to import?

Any ideas to solve this?

1
  • Could you embed them inside one giant XML file? Commented Dec 3, 2019 at 0:43

2 Answers 2

10

Create a base component and register it globally since you'll use it very frequently.


Create a <BaseIcon> component that uses require with expression to create a context for the SVG modules:

<template>
  <Component
     :is="require(`@/assets/svgs/${name}.svg`).default"
     class="BaseIcon"
     v-bind="$attrs"
     @v-on="$listeners"
  />
</template>

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

  // Transparent wrapper component
  // https://v2.vuejs.org/v2/guide/components-props.html#Disabling-Attribute-Inheritance
  inheritAttrs: false,
  
  props: {
    name: {
      type: String,
      required: true,
    },
  },
}
</script>

<style>
 .BaseIcon {
   /* Add some default CSS declaration blocks */
 }
 </style>

Note: We use <Component> to handle dynamic components, which assumes you'll use vue-svg-loader and the SVGs are treated as components. If that is not the case, use an <img> tag instead and use src instead of is.


Registering the base component globally:

If you're only creating a single base component, you can just go to your main.js file and before mounting the app do:

import Vue from 'vue'
import BaseIcon from './components/_base/BaseIcon.vue'
import App from './App.vue'

Vue.component('BaseIcon', BaseIcon)

Vue.config.productionTip = false

new Vue({
  render: h => h(App),
}).$mount('#app')

Else, if you want something a little bit more complex, take a look at how this boilerplate registers base components automatically.


Finally, use the component like so:

<template>
  <div>
    <BaseIcon
      name="info"
    />
    <BaseIcon
      name="help"
    />
    <BaseIcon
      name="close"
    />
  </div>
</template>

<script>
export default {
  name: 'SomeComp',
}
</script>
Sign up to request clarification or add additional context in comments.

3 Comments

Hi @Ricky, thank you very much - looks very accurat. I created the BaseIcon component, added it globaly in main.js and implemented via <BaseIcon name="search" />. But I got an error: Failed to mount component: template or render function not defined. Any idea?
fixed it with: :is="require(@/assets/svgs/${name}.svg).default"
@wittgenstein Chris explains why you need to use default depending on how the module is imported here.
0

Unfortunately, the method described in this answer did not work for me (Vue-CLI 3 + Vue 2).

Examples: External SVG:

    <img :src="require(`@/assets/img/icons/base/config.svg`).default" />

Inline SVG (dynamic component):

    <component :is="require(`@/assets/img/icons/base/config.svg?inline`)" />

Inline SVG (component):

<template><config-icon /></template>
import ConfigIcon from '@/components/icons/config-icon.vue';

Add the code below to vue.config.js:

      chainWebpack: (config) => {
       const svgRule = config.module.rule('svg');

       svgRule.uses.clear();
       svgRule.delete('type');
       svgRule.delete('generator');

       svgRule
        .oneOf('inline')
        .resourceQuery(/inline/)
        .use('babel-loader')
        .loader('babel-loader')
        .end()
        .use('vue-svg-loader')
        .loader('vue-svg-loader')
        .end()
        .end()
        .oneOf('external')
        .use('file-loader')
        .loader('file-loader')
        .options({
          name: 'assets/[name].[hash:8].[ext]',
        });
      },

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.