这篇文章就讲两个事儿:
- 如何在一个组件中使用svg图标。
- 如何将svg图标作为全局资源使用,而不仅限于一个或几个组件中。
如何在一个组件中使用svg图标
先理一下思路:
- 为便于管理,我们把svg图标统一放置在
assets
目录下。 - 使用
MatIconRegistry
服务进行svg图标的注册。也就是使用一个名称,将其与svg图标的路径关联起来,在组件模板上引用这个注册名称就可以了。 - 根据material规范,svg图标的引用路径必须安全可靠,所以要使用Angular的
DomSanitizer
服务标记为可信的。
用代码来逐步实现
假设我们目前有一个组件,名叫HeaderComponent
,初始代码如下:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-header',
template: `
<mat-toolbar color="primary">
<span>顶部</span>
</mat-toolbar>
`
})
export class HeaderComponent implements OnInit {
constructor() {
}
ngOnInit() {
}
}
初始的页面就是这样:
初始.png
要使用MatIconRegistry
和DomSanitizer
服务,我们就得导入它们,代码如下:
import { MatIconRegistry } from '@angular/material/icon';
import { DomSanitizer } from "@angular/platform-browser";
之后在组件的构造函数中调用addSvgIcon
方法,进行图标的注册操作,代码如下:
constructor(ir: MatIconRegistry, ds: DomSanitizer) {
ir.addSvgIcon('icecream', ds.bypassSecurityTrustResourceUrl('assets/ice.svg'));
}
最后,修改组件模板,添加这个注册的svg图标,代码如下:
<mat-toolbar color="primary">
<span>顶部</span>
<mat-icon svgIcon="icecream"></mat-icon>
</mat-toolbar>
这样,图标就能显示出来了。
有了svg图标.png
这是修改后最终的代码:
import { Component, OnInit } from '@angular/core';
import { MatIconRegistry } from '@angular/material/icon';
import { DomSanitizer } from "@angular/platform-browser";
@Component({
selector: 'app-header',
template: `
<mat-toolbar color="primary">
<span>顶部</span>
<mat-icon svgIcon="icecream"></mat-icon>
</mat-toolbar>
`
})
export class HeaderComponent implements OnInit {
constructor(ir: MatIconRegistry, ds: DomSanitizer) {
ir.addSvgIcon('icecream', ds.bypassSecurityTrustResourceUrl('assets/ice.svg'));
}
ngOnInit() {
}
}
将svg图标作为全局资源使用
先泼点儿冷水
上面的代码虽然实现了我们想要的功能,但我们是站在一个组件的角度上,从一个点的高度去看待问题,如果我们站在整个项目的角度上,从一个面的高度去看,那么这种实现方式是有问题的。
- 问题1:重复
我在A组件上能够展现icecream图标了,现在我想要在B组件上也展现这个icecream图标,怎么办?那就把代码复制一份到B组件呗。2个小时后,我又想在C组件上也要有这个图标,那就再复制一份呗。这样的结果就导致了项目中存在了很多重复的代码。
- 问题2:分散
我在A组件里写了注册icecream图标的代码,在B组件里写了注册bike图标的代码,在C组件里写了注册car图标的代码...,这样的结果就导致了注册图标的代码会分散在项目的很多个地方,非常不利于项目的维护。其实这些代码大部分是相同的,都是引用了同样的服务,都是调用了同样的方法,只是注册的名称和svg的路径有区别罢了。
怎么解决呢
方法就是创建一个专门用于注册的工具类。
用代码来逐步实现
在src/app目录下新建一个名为utils的文件夹,并在此文件夹内创建svg.util.ts
文件,文件内容如下:
import { MatIconRegistry } from '@angular/material/icon';
import { DomSanitizer } from "@angular/platform-browser";
export const loadSvgResources = (ir: MatIconRegistry, ds: DomSanitizer) => {
// 注册多个svg图标
ir.addSvgIcon('icecream', ds.bypassSecurityTrustResourceUrl('assets/ice.svg'));
ir.addSvgIcon('lp', ds.bypassSecurityTrustResourceUrl('assets/lp.svg'));
};
然后在核心模块中引入这个工具类,并在核心模块的构造函数中调用loadSvgResources()
方法就可以了,代码如下:
import { MatIconRegistry } from '@angular/material/icon';
import { DomSanitizer } from "@angular/platform-browser";
import { loadSvgResources } from "./utils/svg.util";
...
export class AppModule {
...
constructor(
ir: MatIconRegistry,
ds: DomSanitizer
) {
loadSvgResources(ir, ds);
}
...
}
网友评论