Reputation: 17940
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?
Upvotes: 4
Views: 3460
Reputation: 21
Include an SVG sprite in your markup by making it it's own Vue component. In my case I put the SVG sprite component in App.vue.
App.vue:
<template>
<div class="body">
<YourOtherComponents />
<SvgSprite />
</div>
</template>
<script>
import YourOtherComponents from './Components/YourOtherComponents.vue';
import SvgSprite from './Components/SvgSprite.vue';
export default {
name: 'App',
components: {
YourOtherComponents,
SvgSprite,
},
};
</script>
SvgSprite.vue:
<template>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" style="display: none;">
<symbol id="arrow-left" viewBox="0 0 24 24">
<polyline points="15 18 9 12 15 6"></polyline>
</symbol>
<symbol id="arrow-right" viewBox="0 0 24 24">
<polyline points="9 18 15 12 9 6"></polyline>
</symbol>
</svg>
</template>
<script>
export default {
name: 'SvgSprite',
};
</script>
This way you can the svgs just as if the sprite was inline in your project's index.html file. It's just cleaner.
Upvotes: 0
Reputation: 135812
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>
Upvotes: 6