Search code examples
svgvue.jsstorybook

using svg sprite with vue storybook


I've created an app using the latest Vue CLI.

I'm using vue-storybook to generate a styleguide.

I have an SVG Sprite file under assets called icons.svg and i'd like to create an Icon.vue component that accepts the name of the icon and displays it from the sprite.

The component looks like this:

//currently the href is hardcoded for testing purposes, 
//later on it would be passed as a property
<template>
    <svg class="icon">
        <use xlink:href="../assets/icons.svg#icon-compliance"></use>
    </svg>
</template>

<script>
export default {
  name: "AqIcon"
};
</script>

<style scoped>
.icon {
  display: inline-block;
  width: 1rem;
  height: 1rem;
  fill: red;
}
</style>

And i have a simple story to display it:

storiesOf("Icon", module).add("Icon", () => ({
  components: { AqIcon },
  template: "<AqIcon />"
}));

The problem is the browser tries to load http://localhost:6006/assets/icons.svg and can't find it, I tried all kind of urls but i can't seem to figure out the correct one.

Also, how can i make it dynamic?


Solution

  • You can use require(). Just make sure you don't parameterize its whole args (I mean, leave the folder and extension as hardcoded strings).

    In the example below, WebPack will load all .svg files of the /assets folder (because they may be requested during runtime).

    <template>
        <svg class="icon">
            <use :xlink:href="src"></use>
        </svg>
    </template>
    
    <script>
    export default {
      name: "AqIcon",
      props: ['icon'],
      computed: {
        src() {
          return require('../assets/' + this.icon + '.svg')
        }
      }
    };
    </script>