Angular 元素就是打包成自定义元素的 Angular 组件。所谓自定义元素就是一套与具体框架无关的用于定义新 HTML 元素的 Web 标准。

自定义元素这项特性目前受到了 Chrome、Edge(基于 Chromium 的版本)、Opera 和 Safari 的支持,在其它浏览器中也能通过腻子脚本加以支持。
自定义元素扩展了 HTML,它允许定义一个由 JavaScript 代码创建和控制的标签。 浏览器会维护一个自定义元素的注册表 CustomElementRegistry,它把一个可实例化的 JavaScript 类映射到 HTML 标签上。

创建angular工作空间

  1. ng new workspace_name --create-application=false

安装Angular Elements

  1. ng add @angular/elements --project=project_name

安装ngx-build-plus插件(目的将打包产生的runtime.js等多个js合并成一个js)

  1. ng add ngx-build-plus --project=project_name

处理AppModule

  1. @NgModule({
  2. declarations: [
  3. AppComponent
  4. ],
  5. imports: [
  6. BrowserModule
  7. ],
  8. providers: [],
  9. // bootstrap: [AppComponent]
  10. })
  11. export class AppModule {
  12. constructor(private injector: Injector){
  13. }
  14. ngDoBootstrap(){
  15. const customElement = createCustomElement(AppComponent,{injector: this.injector});
  16. customElements.define("my-element",customElement);
  17. }
  18. }

在package.json添加一条新的script

  1. "script": {
  2. ...,
  3. "build:my-custom-element": "ng build --prod --output-hashing=none --single-bundle"
  4. }

image.png
此时在dist文件中就会产生自定义HTML标签的main.js

支持Angular 中的@Input() @Output()装饰器

  1. import { Component, EventEmitter, Input, NgZone, Output } from '@angular/core';
  2. @Component({
  3. selector: 'app-root',
  4. templateUrl: './app.component.html',
  5. styleUrls: ['./app.component.css']
  6. })
  7. export class AppComponent {
  8. title = 'test-custom-element';
  9. @Input() inputProperty;
  10. @Output() clickThing = new EventEmitter();
  11. constructor(private zone: NgZone){
  12. }
  13. clickMethod(){
  14. this.clickThing.emit("output测试中");
  15. this.zone.runOutsideAngular(() => {
  16. });
  17. }
  18. }
  1. window.onload = () => {
  2. const element = document.getElementById("test");
  3. element.inputProperty = '44444444444';
  4. element.addEventListener('clickThing',(ev) => alert(ev.detail));
  5. }

在Angular项目中引入自定义元素

在angular项目添加@angular-extensions/elements

  1. ng add @angular-extensions/elements

在AppModule中引入LazyElementsModule

  1. import { LazyElementsModule } from '@angular-extensions/elements';
  2. import { CUSTOM_ELEMENTS_SCHEMA, Injector, NgModule } from '@angular/core';
  3. import { createCustomElement } from '@angular/elements';
  4. import { BrowserModule } from '@angular/platform-browser';
  5. import { AppComponent } from './app.component';
  6. @NgModule({
  7. declarations: [
  8. AppComponent,
  9. ],
  10. imports: [
  11. BrowserModule,
  12. LazyElementsModule // 引入
  13. ],
  14. schemas: [CUSTOM_ELEMENTS_SCHEMA], // 引入
  15. providers: [],
  16. bootstrap: [AppComponent]
  17. })
  18. export class AppModule {
  19. }

在component.html中添加指令即可

  1. <my-element *axLazyElement="elementUrl"></my-element>
  2. <!-- elementUrl指的是自定义元素的js地址 -->

在非Angular项目中引入自定义元素

在原生html,React,Vue项目中引入打包产生的js,还需要引入zone.min.js。

MDN链接🔗 : https://developer.mozilla.org/zh-CN/docs/Web/API/Window/customElements