如何将 svg 从文件导入 angular 5 中的组件?

mr_*_*ond 16 html import svg angular-universal angular

我发现所有将 svg 添加到 AngularCli 组件的教程都建议将其插入到 html 模板中,如下所示:

<div>
  <svg viewBox="0 0 250 250">
    <svg:g class="group">
       <svg:polygon class="shield" points="125,30 125,30 125,30 31.9,63.2 46.1,186.3 125,230 125,230 125,230 203.9,186.3 218.1,63.2" />
       <svg:path class="a" d="M125,52.1L66.8,182.6h0h21.7h0l11.7-29.2h49.4l11.7,29.2h0h21.7h0L125,52.1L125,52.1L125,52.1L125,52.1
      L125,52.1z M142,135.4H108l17-40.9L142,135.4z"/>
    </svg:g>
  </svg>
</div>
Run Code Online (Sandbox Code Playgroud)

但我希望保持模板清晰,并且只在其中插入几个带有 url 的标签到分隔的 svg 文件,就像这样:

<svg class="star">
        <use xlink:href="../../../assets/images/svg/star.svg"
               x="0"
               y="0" />
</svg>
Run Code Online (Sandbox Code Playgroud)

如何在组件中使用分离的 svg 文件?

jsn*_*bie 19

TL;DR,用于HttpClient获取文件,然后用于bypassSecurityTrustHtml使用[innerHTML].

这可能有点晚了,但我们是这样找到解决方案的。我们尝试研究有角度的材料如何为他们的图标做到这一点,天哪,我们惊讶地发现它确实如此简单。HttpClient他们只是使用!来获取文件。它已经在我们的脑海中,但我们一直忽略它,因为我们认为也许有更好的解决方案。

因此,经过几分钟的搜索,我们偶然发现了这一点:https: //github.com/angular/components/blob/653457eaf48faab99227f37bc2fe104d9f308787/src/material/icon/icon-registry.ts#L621

所以基本上,如果你的 SVG 文件位于你的资源文件夹 ( /assets/images/svg/star.svg) 中,你所要做的就是使用 来获取它HttpClient.get并使用 来DomSanitizer绕过安全性并信任给定的值是安全的 HTML,然后才能将其渲染到你的组件。

最后,我们的组件如下所示:

import { Component, OnChanges, SecurityContext } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { DomSanitizer } from '@angular/platform-browser';

@Component({
  selector: 'app-svg-icon',
  template: `<span [innerHTML]="svgIcon"></span>`,
  styleUrls: ['./svg-icon.component.scss'],
})
export class SvgIconComponent implements OnChanges {

  @Input()
  public name?: string;

  public svgIcon: any;

  constructor(
    private httpClient: HttpClient,
    private sanitizer: DomSanitizer,
    ) {
  }

  public ngOnChanges(): void {
    if (!this.name) {
      this.svgIcon = '';
      return;
    }
    this.httpClient
      .get(`assets/images/svg/${this.name}.svg`, { responseType: 'text' })
      .subscribe(value => {
        this.svgIcon = this.sanitizer.bypassSecurityTrustHtml(value);
      });
  }

}

Run Code Online (Sandbox Code Playgroud)

现在您可以将组件导入应用程序中的任何位置,如下所示

<app-svg-icon name="star"></app-svg-icon>
Run Code Online (Sandbox Code Playgroud)

  • @mhombach 这通常就是 mat-icon 库的工作方式,并且创建该功能是有原因的。您只需要知道何时以及如何使用它即可。干杯! (2认同)

Bor*_*hik 17

如果你有logo.svg

  1. 把它放在你的src/assets文件夹里
  2. angular.json配置中包含文件夹:"assets": [ "src/assets" ]
  3. 从模板中引用它: <img src="assets/svg/logo.svg">


小智 14

将您的 SVG 文件包含在 src/assets 文件夹中,并在您的angular.json文件中添加 svg 文件夹。

"assets": [ "src/assets/svg/*" ]
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以根据需要将文件包含在组件中。

  • 如果它是一个lib怎么办?当我尝试运行位于同一工作区并使用库的应用程序时,它收到以下错误:`发生未处理的异常:projects/my-lib/src/assets 资产路径必须以项目源开头根`。但如果我从“src”开始,它就无法知道我指的是库还是应用程序。从“projects”开始以相同的方式引用应用程序的资产文件夹效果很好 (3认同)

Ary*_*a11 8

一种方法是为 svg 文件设置 id 属性,并将 svg 文件放入 asset 文件夹中。然后在 mat-icon 中使用该 id,如下所示:

<mat-icon svgIcon="my-star-icon"></mat-icon>
Run Code Online (Sandbox Code Playgroud)

这是一个更好的方法;这样您就不必在 UI html 代码中处理 svg 标签。这也支持谷歌图标。

不过,如果您使用的是有角度的材料,这会起作用。

编辑: 您需要在组件中使用 IconRegistry 注册图标才能正常工作:

<mat-icon svgIcon="my-star-icon"></mat-icon>
Run Code Online (Sandbox Code Playgroud)

检查此处的文档和此处的示例。

  • 这需要使用 Angular Material 进行额外设置。你能用这些更新你的答案吗?如果没有,我可以继续编辑您的答案。 (5认同)