在Material UI中使用svg图标

这篇文章就讲两个事儿:

  • 如何在一个组件中使用svg图标。
  • 如何将svg图标作为全局资源使用,而不仅限于一个或几个组件中。

如何在一个组件中使用svg图标

先理一下思路:

  • 为便于管理,我们把svg图标统一放置在assets目录下。
  • 使用MatIconRegistry服务进行svg图标的注册。也就是使用一个名称,将其与svg图标的路径关联起来,在组件模板上引用这个注册名称就可以了。
  • 根据material规范,svg图标的引用路径必须安全可靠,所以要使用Angular的DomSanitizer服务标记为可信的。

用代码来逐步实现

假设我们目前有一个组件,名叫HeaderComponent,初始代码如下:

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

@Component({
  selector: 'app-header',
  template: `
    
      顶部
    
  `
})
export class HeaderComponent implements OnInit {

  constructor() {
  }

  ngOnInit() {
  }
}

初始的页面就是这样:


初始.png

要使用MatIconRegistryDomSanitizer服务,我们就得导入它们,代码如下:

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图标,代码如下:


      顶部
      
  

这样,图标就能显示出来了。


有了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: `
    
      顶部
      
    
  `
})
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);
  }

...

}

你可能感兴趣的:(在Material UI中使用svg图标)