And*_*Mao 12 javascript svg typescript rollupjs svelte
我有大约 80 个自定义 SVG 图标,我将它们导入到 Svelte 前端应用程序中。它基于https://github.com/sveltejs/template构建,使用 Rollup 构建,包括 Typescript、Tailwind 和所有现代好东西。
困境在于如何将图标添加到应用程序中。作为 SVG,图标是不超过 2kB 的简短 XML 文本字符串。
foo.svg到public/assets/icons.<Icon type="foo' />使用<img src="foo.svg>.这种方法意味着图标不是代码的一部分。
优点:图标可以由前端代码按需动态加载。无需将所有图标捆绑到应用程序代码中。
缺点:如果有很多新图标,页面加载速度会很慢,并且浏览器必须获取十几个 1kB 文件。将应用程序部署为 PWA 意味着我们需要手动告诉它预先缓存图标。
import Home from './icons/home.svg';在这里,图标作为文本字符串与应用程序本身捆绑在一起。
优点:图标作为应用程序包的一部分提供。缓存是不必要的。可以在加载时动态修改一些图标代码,例如颜色、视图框等。
缺点:没有必要在应用程序中包含所有图标以减少到第一个字节的时间。不能在不增加复杂性的情况下进行捆绑拆分等。使渲染变慢,因为 Javascript 代码需要首先将字符串转换为 SVG,而不仅仅是加载图像。
Bob*_*kes 19
您想保持 SVG 图标文件不变吗?
Vite 的导入选项?raw可用于此目的,导入 SVG 图标文件的原始内容。此选项在此描述https://vitejs.dev/guide/assets.html#importing-asset-as-string
使用 svelte{@html }选项,它将以原始 html 格式输出。
它将结合问题中的选项 1 如何解释不将图标作为代码的一部分,但仍导入图标以使其成为应用程序构建的一部分,如问题的选项 2 中所述。
主要好处是 SVG 图标库可以通过 *.svg 扩展名保持原始状态。例如:
import SearchIcon from '$lib/icon/search.svg?raw';
{@html SearchIcon}
Run Code Online (Sandbox Code Playgroud)
代码中只会包含应用程序功能所需的 SVG 图标。这确保了应用程序保持轻量级和高效。
尽管我也会考虑将 SVG 文件重新制作成 .svelte 文件的方案,就像另一个答案中提出的那样。我刚刚提出了 Vite?raw功能,以防最好保持图标文件不变。与往常一样,使用时@html请确保图标是“受信任”的 html 文件并且无法(重新)生成。$lib/icon/*.svg因此,像原始 SVG 文件那样的文件路径是一个安全的解决方案。
小智 9
另一种方法是在公共文件夹中使用符号定义文件(例如:icons.svg)。然后在你的代码中做这样的事情:
图标.svelte
<script>
export let name;
export let width = "1.5rem";
export let height = "1.5rem";
export let focusable = false;
</script>
<svg class={$$props.class} {focusable} {width} {height}>
<use href={`/icons.svg#${name}`} />
</svg>
Run Code Online (Sandbox Code Playgroud)
图标.svg
<svg aria-hidden="true" style="position: absolute; width: 0; height: 0; overflow: hidden;" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<defs>
<symbol id="icon-warning" viewBox="0 0 20 20">
<path d="M19.511 17.98l-8.907-16.632c-0.124-0.215-0.354-0.348-0.604-0.348s-0.481 0.133-0.604 0.348l-8.906 16.632c-0.121 0.211-0.119 0.471 0.005 0.68 0.125 0.211 0.352 0.34 0.598 0.34h17.814c0.245 0 0.474-0.129 0.598-0.34 0.124-0.209 0.126-0.469 0.006-0.68zM11 17h-2v-2h2v2zM11 13.5h-2v-6.5h2v6.5z">
</path>
</symbol>
</defs>
</svg>
Run Code Online (Sandbox Code Playgroud)
应用程序.svelte
<Icon name="icon-warning" />
Run Code Online (Sandbox Code Playgroud)
这样你就可以使用一个 http 调用来加载 svg 文件。然后只需在标记中使用您需要的部分即可。
使用 like{@html SVG_CODE}从另一个组件或变量渲染 svg 代码是一个糟糕的选择。这有时会带来XSS 攻击的风险。特别是当图像来自外部源时。检查: https: //github.com/sveltejs/svelte/issues/2545
在插入 DOM 之前,Svelte 不会对 {@html ...} 内的表达式执行任何清理。换句话说,如果您使用此功能,手动转义来自您不信任的来源的 HTML 至关重要,否则您的用户将面临 XSS 攻击的风险。(来源)
我认为使用像rollup-plugin-svelte-svg 这样的插件会是更好的选择
npm i -D rollup-plugin-svelte-svg
export default {
plugins: [
svelteSVG({
// optional SVGO options
// pass empty object to enable defaults
svgo: {}
}),
],
...
}
Run Code Online (Sandbox Code Playgroud)
<script>
import Logo from "./logo.svg";
</script>
<Logo width=20 />
Run Code Online (Sandbox Code Playgroud)
.svelte扩展名为 .svg 的文件中。例如,
icon.svg文件包含:
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M14.243 5.757a6 6 0 10-.986 9.284 1 1 0 111.087 1.678A8 8 0 1118 10a3 3 0 01-4.8 2.401A4 4 0 1114 10a1 1 0 102 0c0-1.537-.586-3.07-1.757-4.243zM12 10a2 2 0 10-4 0 2 2 0 004 0z" clip-rule="evenodd"></path></svg>
Run Code Online (Sandbox Code Playgroud)
icon.svelte文件中<script></script>
<style></style>
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M14.243 5.757a6 6 0 10-.986 9.284 1 1 0 111.087 1.678A8 8 0 1118 10a3 3 0 01-4.8 2.401A4 4 0 1114 10a1 1 0 102 0c0-1.537-.586-3.07-1.757-4.243zM12 10a2 2 0 10-4 0 2 2 0 004 0z" clip-rule="evenodd"></path></svg>
Run Code Online (Sandbox Code Playgroud)
icon.svelte组件时<script>
import Icon from "$lib/icon.svelte"
</script>
<style></style>
<Icon />
Run Code Online (Sandbox Code Playgroud)
然后在icon.svelte
<script></script>
<style></style>
<svg class="{$$props.class}" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M14.243 5.757a6 6 0 10-.986 9.284 1 1 0 111.087 1.678A8 8 0 1118 10a3 3 0 01-4.8 2.401A4 4 0 1114 10a1 1 0 102 0c0-1.537-.586-3.07-1.757-4.243zM12 10a2 2 0 10-4 0 2 2 0 004 0z" clip-rule="evenodd"></path></svg>
Run Code Online (Sandbox Code Playgroud)
icon.svelte组件时<script>
import Icon from "$lib/icon.svelte"
</script>
<style></style>
<Icon class="h-6 w-6" />
Run Code Online (Sandbox Code Playgroud)
以下方法具有以下优点:
有一个专用的 Icon.svelte 组件设置,如下所示:
<script>
export let name;
export let width = "1rem";
export let height = "1rem";
export let focusable = false;
let icons = [
{
box: 24,
name: "save",
svg: `<g stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11l5 5v11a2 2 0 0 1-2 2z"/><path d="M17 21v-8H7v8"/><path d="M7 3v5h8"/></g>`
},
{
box: 32,
name: "trash",
svg: `<path d="M12 12h2v12h-2z" /><path d="M18 12h2v12h-2z" /><path d="M4 6v2h2v20a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V8h2V6zm4 22V8h16v20z" /><path d="M12 2h8v2h-8z" />`
}
];
let displayIcon = icons.find((e) => e.name === name);
</script>
<svg
class={$$props.class}
{focusable}
{width}
{height}
viewBox="0 0 {displayIcon.box} {displayIcon.box}">{@html displayIcon.svg}</svg>
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样使用它:
<Icon name="trash" class="this-is-optional" />
Run Code Online (Sandbox Code Playgroud)
小智 4
一个可行的解决方案是将 SVG 保存在单独的 IconService.js 中:
export const chevron_down = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"feather feather-chevron-down\"><polyline points=\"6 9 12 15 18 9\"></polyline></svg>";
export const chevron_right = "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"feather feather-chevron-right\"><polyline points=\"9 18 15 12 9 6\"></polyline></svg>";
Run Code Online (Sandbox Code Playgroud)
这可以轻松地在 svelte @html 函数中导入和使用。
<script>
import {chevron_down, chevron_right} from 'IconService';
</script>
{@html chevron_down}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3793 次 |
| 最近记录: |