我正在构建一个Angular应用程序(Angular 4/5/6),并希望在我的组件模板中使用SVG sprite。
问题:
假设我已经生成了我的SVG图标精灵(icons.svg
),我如何让Angular将我的SVG图标精灵注入/导入我的组件模板?
有没有办法将我的SVG图标精灵注入/导入我的组件而不必使用任何第三方模块/指令,并使用Angular本身进行本地操作?
背景/问题:
如this article中所述,icons.svg
文件将包含定义为<symbol>
的所有SVG图标。然后我可以使用<use>
在我的HTML中呈现选定的图标,假设在{DOM}中注入了icons.svg
。
我使用IcoMoon app生成了SVG精灵,并将icons.svg
保存到我的Angular应用程序中。下面是我的示例Angular组件( app.component.ts ),其中我试图注入/导入icons.svg
文件并尝试在我的HTML中呈现SVG图标。但是,Angular并没有依赖我的SVG图标。我似乎错误地注入了SVG图标精灵文件。
更新:
icons.svg
,并在我使用它时让它在HTML中呈现它们。app.component.ts :StackBlitz上的实例:https://stackblitz.com/edit/angular-bbr2kh?file=src/app/app.component.ts
import { Component } from '@angular/core';
// import `./icons.svg`; // This import method doesn't work
@Component({
selector: 'my-app',
template: `
<!-- This import method doesn't work -->
<!-- <script src="./icons.svg"></script> -->
<p>
Hello this is a sample Angular 6 component.
</p>
<p>Testing to see if SVG icon sprite import works. See below if icons appear. </p>
<p>Icon (home): <svg class="icon icon-home"><use xlink:href="#icon-home"></use></svg> </p>
<p>Icon (rocket): <svg class="icon icon-rocket"><use xlink:href="#icon-rocket"></use></svg> </p>
<p>Icon (wifi): <svg class="icon icon-connection"><use xlink:href="#icon-connection"></use></svg>
<!-- This import method doesn't work -->
<!-- <p>Icon (home): <svg class="icon icon-home"><use xlink:href="./icons.svg#icon-home"></use></svg> </p>-->
</p>
`,
styles: [`
.icon {
display: inline-block;
width: 1em;
height: 1em;
stroke-width: 0;
stroke: currentColor;
fill: currentColor;
}
`]
})
export class AppComponent {
}
答案 0 :(得分:2)
我认为您的根源就是您遇到问题的地方。在您的代码中,您告诉angular在app
中查找,但浏览器将其视为https://your-site.com./icons
如果将图标文件移动到/assets
文件夹下,则src\assets
集合将告诉您angular.json
文件夹中已经包含"assets"
文件夹,因此该图标文件应该已经可用角度看哪里。
<svg class="icon">
<use xlink:href="/assets/icons.svg#icon-rocket"></use> // Notice root path not "./"
</svg>
如果您希望从另一个目录提供文件,您要做的就是在angular.json中添加一个路径:
…
"assets": [
"src/favicon.ico",
"src/assets",
"src/your-dir"
],
…
然后在您的代码中
<svg class="icon">
<use xlink:href="/your-dir/icons.svg#icon-rocket"></use>
</svg>
我不建议添加/src/app
作为资产路径,这基本上可以打开整个应用程序来提供文件,从而使整个目录都可以访问。
我分叉了您的示例,并更新了here
答案 1 :(得分:0)
今天我和您在同一条船上,设计师们回头介绍了svg字体。我也不想将图标def从node_modules中移出,因为它会随着时间变化。我想出了一个解决方案。
您需要首先创建一个有角度的图标组件,然后执行以下操作:
import { Component, OnInit, Input } from '@angular/core';
declare const require;
@Component({
selector: 'my-icon',
templateUrl: './my-icon.component.html',
styleUrls: ['./my-icon.component.scss']
})
export class IconComponent implements OnInit {
constructor() { }
@Input() icon: string = "";
@Input() x: string = "0";
@Input() y: string = "0";
@Input() fillColor: string = "black";
@Input() strokeColor: string = "black";
@Input() height: string = "";
@Input() width: string = "";
private baseUrl: string = require("../../../../../node_modules/path/to/defs.svg") + "#beginning-of-iconset-";
svgUrl: string = "";
ngOnInit() {
}
ngAfterViewInit() {
setTimeout(()=>{
this.svgUrl = this.baseUrl + this.icon;
},0);
}
}
然后在html中:
<svg [attr.height]="height" [attr.width]="width" xmlns="http://www.w3.org/2000/svg">
<use [attr.href]="svgUrl" [attr.x]="x" [attr.y]="y" [attr.fill]="fillColor" [attr.stroke]="strokeColor" />
</svg>
由于width和height属性无法按预期工作,我仍在扩展解决方案。我也知道,您也可以扩展输入。
希望有帮助。
答案 2 :(得分:0)
我使用角形材质图标解决了这个问题。
角度材料按id注入SVG,并且没有 shadow-dom 。
首先安装角材:
"@angular/material": "^7.3.7", // change version according to your angular version
导入您的模块:
MatIconModule
然后在app.component或服务中声明您的SVG精灵。
constructor(
private matIconRegistry: MatIconRegistry,
private domSanitizer: DomSanitizer) {
matIconRegistry.addSvgIconSet(this.domSanitizer.bypassSecurityTrustResourceUrl(`assets/sprite.svg`));
}
最后,在HTML中使用角度材质图标:
<mat-icon svgIcon="svg-id"></mat-icon> // or use as directive <div svgIcon="svg-id"></div>
答案 3 :(得分:-1)
您可以将您的svg文件转换为https://icomoon.io/app/#/select字体,上传您的svg文件并选择它,单击Generate Font然后单击下载按钮, 下载字体文件并选择字体文件夹并将其放在项目的文件夹中,
将字体文件导入css文件
@font-face {
font-family: 'icomoon';
src: url('fonts/icomoon.eot?31svmk');
src: url('fonts/icomoon.eot?31svmk#iefix') format('embedded-opentype'),
url('fonts/icomoon.ttf?31svmk') format('truetype'),
url('fonts/icomoon.woff?31svmk') format('woff'),
url('fonts/icomoon.svg?31svmk#icomoon') format('svg');
font-weight: normal;
font-style: normal;
}
像你这样谴责你的班级
.icon-home:before {
content: "\ea77";
}
.icon-conection:before {
content: "\ea78";
}
.icon-rocket:before {
content: "\ea79";
}
并在你的html中使用它
<p>Icon (rocket): <i class="icon-rocket"></i> </p>
解决方案是在项目中添加图标,但如果要在项目中使用svg代码,最好将加载器添加到项目中。
如果您使用过网络包:
npm install svg-inline-loader --save-dev
只需将配置对象添加到module.loader就可以了。
{
test: /\.svg$/,
loader: 'svg-inline-loader'
}