Icon - 图1 This article has not been translated, hope that your can PR to translated it. Help us!Icon - 图2

Icon

自 ng-zorro-antd 1.7.x 以后图标发生破坏性变更,虽然带了诸多优势,同时也带来几个劣势:

  • 若采用动态加载会产生额外的HTTP请求

  • 若静态加载需要逐一注册图标

  • st 组件的 format 参数无法直接指定图标

ng-alain 默认使用静态加载的做法,毕竟后端使用图标相对于比较有限,即使将 svg 都打包进脚本相比较之前整个 styles 体积上是所有减少,但比较并不多。

而针对以上问题,ng-alain 提供几种方案。

使用icon插件(推荐)

尽可能从项目中分析并生成静态 Icon,插件会自动在 src 目录下生成两个文件:

  • src/style-icons.ts 自定义部分无法解析(例如:远程菜单图标)

  • src/style-icons-auto.ts 命令自动生成文件

自动排除 ng-zorro-antd@delon 已经加载的图标。

  1. ng g ng-alain:plugin icon

同时,需要手动在 startup.service.ts 中导入:

  1. import { ICONS_AUTO } from '../../../style-icons-auto';
  2. import { ICONS } from '../../../style-icons';
  3. @Injectable()
  4. export class StartupService {
  5. constructor(iconSrv: NzIconService) {
  6. iconSrv.addIcon(...ICONS_AUTO, ...ICONS);
  7. }
  8. }

有效语法

  1. <i class="anticon anticon-user"></i>
  2. <i class="anticon anticon-question-circle-o"></i>
  3. <i class="anticon anticon-spin anticon-loading"></i>
  4. <i nz-icon class="anticon anticon-user"></i>
  5. <i nz-icon nzType="align-{{type ? 'left' : 'right'}}"></i>
  6. <i nz-icon [type]="type ? 'menu-fold' : 'menu-unfold'" [theme]="theme ? 'outline' : 'fill'"></i>
  7. <i nz-icon [type]="type ? 'fullscreen' : 'fullscreen-exit'"></i>
  8. <i nz-icon nzType="{{ type ? 'arrow-left' : 'arrow-right' }}"></i>
  9. <i nz-icon nzType="filter" theme="outline"></i>
  10. <nz-input-group [nzAddOnBeforeIcon]="focus ? 'anticon anticon-arrow-down' : 'anticon anticon-search'"></nz-input-group>

动态加载

动态加载,这是为了减少包体积而提供的方式。当 NG-ZORRO 检测用户想要渲染的图标还没有静态引入时,会发起 HTTP 请求动态引入。你只需要配置 angular.json 文件:

  1. {
  2. "assets": [
  3. {
  4. "glob": "**/*",
  5. "input": "./node_modules/@ant-design/icons-angular/src/inline-svg/",
  6. "output": "/assets/"
  7. }
  8. ]
  9. }

动态使用

不管是静态或动态加载,依然无法解决原始方法 class="anticon anticon-" 的便利性,毕竟字符串就是字符串并非 Angular 模板无法被解析,而针对这个问题,提供两种解决办法。

类样式

事实上所有 Antd 图标都可以在 iconfont 找得到,可以点选自己需要的图标并生成相应的 css 文件或 cdn,最后在项目中可以直接使用 1.7.0 之前的写法。

注意: 在项目编辑里加上 anticon anticon- 前缀才能同之前的类名保持一致。

  1. // angular.json
  2. "styles": [
  3. "src/iconfont.css"
  4. ],

如果非cdn还需要将相应的 icon 图标文件复制到 assets 目录下,同时修改 iconfont.css@font-face 对应的 url 路径。

@angular/elements

动态加载的另一种方式是使用 @angular/elements,只需要 nz-icon 指令重新封装成组件。

  1. import { Component, Input } from '@angular/core';
  2. @Component({
  3. selector: 'nz-icon',
  4. template: `<i nz-icon [type]="type"></i>`,
  5. })
  6. export class IconComponent {
  7. @Input()
  8. type: string;
  9. }

同时在根模块里注册它。

  1. import { createCustomElement } from '@angular/elements';
  2. @NgModule({
  3. declarations: [],
  4. })
  5. export class AppModule {
  6. constructor(injector: Injector) {
  7. customElements.define('nz-icon', createCustomElement(IconComponent, { injector }));
  8. }
  9. }

最后。

  1. @Component({
  2. selector: 'app-demo',
  3. template: `
  4. <div [innerHTML]="value"></div>
  5. `,
  6. })
  7. export class DemoComponent {
  8. constructor(private san: DomSanitizer) { }
  9. value = this.san.bypassSecurityTrustHtml(
  10. `icon: `,
  11. );
  12. }