美文网首页
在Material UI中使用svg图标

在Material UI中使用svg图标

作者: BigDipper | 来源:发表于2019-02-15 16:09 被阅读0次

    这篇文章就讲两个事儿:

    • 如何在一个组件中使用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

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

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

    相关文章

      网友评论

          本文标题:在Material UI中使用svg图标

          本文链接:https://www.haomeiwen.com/subject/ptfpeqtx.html