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

问题描述 投票:0回答:9
html angular svg import angular-universal
9个回答
45
投票

如果您有

logo.svg

  1. 将其放入您的
    src/assets
    文件夹
  2. angular.json
    配置中包含文件夹:
    "assets": [ "src/assets" ]
  3. 参考模板:
    <img src="assets/svg/logo.svg">

20
投票

将您的 SVG 文件包含在 src/assets 文件夹中,并将 svg 文件夹添加到您的

angular.json
文件中。

"assets": [ "src/assets/svg/*" ]

这样您就可以根据需要将该文件包含在组件中。


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);
      });
  }

}

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

<app-svg-icon name="star"></app-svg-icon>

8
投票

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

<mat-icon svgIcon="my-star-icon"></mat-icon>

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

尽管如果您使用的是有角度的材料,这也是可行的。

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

  constructor(iconRegistry: MatIconRegistry, sanitizer: DomSanitizer) {
    iconRegistry.addSvgIcon(
        'my-star-icon',
        sanitizer.bypassSecurityTrustResourceUrl('assets/icons/my-star-icon.svg'));
  }

查看文档此处和示例此处


3
投票

还有一种更优雅的方法,但这意味着 svg 文件具有与文件名相同的 ID。

Svg 组件:

import { Component, Input, OnInit } from '@angular/core';

@Component({
  selector: 'app-svg-icon',
  template: '
    <svg attr.width="{{width}}px" attr.height="{{height}}px" attr.fill="{{fill}}" attr.class="{{class}}">
      <use attr.xlink:href="assets/icons/{{icon}}.svg#{{icon}}"></use>
    </svg>
  ',
})
export class SvgIconComponent implements OnInit {
  @Input() icon!: string;
  @Input() width?: number;
  @Input() height?: number;
  @Input() size?: number = 24;
  @Input() fill?: string;
  @Input() class?: string;

  ngOnInit(): void {
    if (!this.width || !this.height) {
      this.width = this.size;
      this.height = this.size;
    }
  }
}

假设您的文件夹中有 svg:/assets/icons/person.svg

svg 本身包含以下代码(以便您可以轻松更改 svg 的大小和颜色,它不应包含高度、宽度和填充属性):

<svg id="person" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
    <path d="M12 5.9c1.16 0 2.1.94 2.1 2.1s-.94 2.1-2.1 2.1S9.9 9.16 9.9 8s.94-2.1 2.1-2.1m0 9c2.97 0 6.1 1.46 6.1 2.1v1.1H5.9V17c0-.64 3.13-2.1 6.1-2.1M12 4C9.79 4 8 5.79 8 8s1.79 4 4 4 4-1.79 4-4-1.79-4-4-4zm0 9c-2.67 0-8 1.34-8 4v3h16v-3c0-2.66-5.33-4-8-4z" />
</svg>

现在您可以在任何组件中使用您的图标:

<app-svg-icon [icon]="'person'" fill="red" [size]="48"></app-svg-icon>


2
投票

所以我试图做到这一点,在我的一生中,我无法让这个 svg 显示出来,直到......经过多次互联网搜索,我不认为这只是我,如果你复制意大利面路径互联网那么也许你忘了包含这个

xmlns="http://www.w3.org/2000/svg"

<svg xmlns="http://www.w3.org/2000/svg" height="100" width="100">
<path d="I love copying and pasting paths"/>
</svg>

然后你就可以继续做你的

 <img src="assets/img/logo.svg" />

如果这不起作用,并且您想使用图像,则将图像放入

assets/img/copypasta.png


0
投票

使用 SVG 作为模板

您可以直接使用 SVG 而不是 HTML 作为组件模板来完成 - 更多详细信息这里

工作示例此处

@Component({
  selector: 'app-my-svg',
  templateUrl: './my-svg.component.svg',
  styleUrls: ['./my-svg.component.css']
})
export class MySvgComponent {
...

在此 SVG 模板(位于单独的文件中!)中,您可以以角度方式使用样式和变量


0
投票

Angular - 创建另一个组件,添加很多东西等,然后获取你的 svg。

React - 只需导入您的 svg 即可继续工作。

(是的,它将被添加为标签。您可以用 css 填充它,随意更改它)

Compare React and Angular imort of SVG


0
投票

2024 版本。在我以编程方式设置innerHtml 之前,该图标不可见。还要注意身份验证拦截器,向 get 请求添加标头可能会导致其失败并出现空错误。

import { HttpClient } from '@angular/common/http';
import { ChangeDetectionStrategy, Component, ElementRef, HostBinding, Input, OnChanges, OnInit, ViewChild, ViewEncapsulation } from '@angular/core';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { Router } from '@angular/router';

@Component({
  selector: 'app-icon',
  template: `<span #svgContainer></span>`,
  changeDetection: ChangeDetectionStrategy.OnPush,
  encapsulation: ViewEncapsulation.None,
})
export class IconComponent implements OnChanges {

  @Input() src?: string;
  svgIcon?: any;
  @ViewChild('svgContainer', { static: true }) svgContainerRef!: ElementRef;
  @HostBinding('style.display') display = 'inline-flex';

  constructor(private http: HttpClient, private sanitizer: DomSanitizer, private router: Router) { }

  ngOnChanges() {
    if (!this.src) return;
    this.http.get(this.src, { responseType: 'text' }).subscribe((data) => {
      const div = this.svgContainerRef.nativeElement;
      if (div) {
        div.innerHTML = data;
      }
    });
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.