将 svg sprite 与 vue 故事书一起使用
using svg sprite with vue storybook
我使用最新的 Vue CLI.
创建了一个应用程序
我正在使用 vue-storybook 生成样式指南。
我在名为 icons.svg 的资产下有一个 SVG Sprite 文件,我想创建一个 Icon.vue 组件,它接受图标的名称并从 sprite 显示它。
组件如下所示:
//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>
我有一个简单的故事来展示它:
storiesOf("Icon", module).add("Icon", () => ({
components: { AqIcon },
template: "<AqIcon />"
}));
问题是浏览器试图加载 http://localhost:6006/assets/icons.svg
但找不到它,我尝试了所有类型的网址,但我似乎无法找到正确的网址。
还有,我怎样才能使它动态化?
您可以使用 require()
。只要确保你没有参数化它的整个参数(我的意思是,将文件夹和扩展名保留为硬编码字符串)。
在下面的示例中,WebPack 将加载 /assets
文件夹中的所有 .svg
文件(因为它们可能在运行时被请求)。
<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>
通过使其成为自己的 Vue 组件,在您的标记中包含 SVG 精灵。在我的例子中,我将 SVG 精灵组件放在 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>
通过这种方式,您可以获得 svgs,就好像 sprite 内嵌在项目的 index.html 文件中一样。只是更干净。
我使用最新的 Vue CLI.
创建了一个应用程序我正在使用 vue-storybook 生成样式指南。
我在名为 icons.svg 的资产下有一个 SVG Sprite 文件,我想创建一个 Icon.vue 组件,它接受图标的名称并从 sprite 显示它。
组件如下所示:
//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>
我有一个简单的故事来展示它:
storiesOf("Icon", module).add("Icon", () => ({
components: { AqIcon },
template: "<AqIcon />"
}));
问题是浏览器试图加载 http://localhost:6006/assets/icons.svg
但找不到它,我尝试了所有类型的网址,但我似乎无法找到正确的网址。
还有,我怎样才能使它动态化?
您可以使用 require()
。只要确保你没有参数化它的整个参数(我的意思是,将文件夹和扩展名保留为硬编码字符串)。
在下面的示例中,WebPack 将加载 /assets
文件夹中的所有 .svg
文件(因为它们可能在运行时被请求)。
<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>
通过使其成为自己的 Vue 组件,在您的标记中包含 SVG 精灵。在我的例子中,我将 SVG 精灵组件放在 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>
通过这种方式,您可以获得 svgs,就好像 sprite 内嵌在项目的 index.html 文件中一样。只是更干净。