当前的 Angular 版本不提供将组件导出为单个本地文件的选项,该文件可用于任何非 Angular 应用程序。但是,可以通过更改构建和部署步骤来实现。在我的示例中,我创建了两个角度元素一个按钮和警报消息。这两个组件都被编译并导出为单个本地文件,我使用 javascript 将其加载到纯 html 文件中。
步骤如下: 1. 在entryComponent 列表中添加ButtonComponent 和AlertComponent。在 ngDoBootstrap 中并将它们定义为自定义元素。这就是我的 app.module 的外观:
import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Injector } from '@angular/core';
import { createCustomElement } from '@angular/elements';
import { AppComponent } from './app.component';
import { ButtonComponent } from './button/button.component';
import { AlertComponent } from './alert/alert.component';
@NgModule({
declarations: [AppComponent, ButtonComponent, AlertComponent],
imports: [BrowserModule],
entryComponents: [ButtonComponent, AlertComponent]
})
export class AppModule {
constructor(private injector: Injector) {
}
ngDoBootstrap() {
const customButton = createCustomElement(ButtonComponent, { injector: this.injector });
customElements.define('my-button', customButton);
const alertElement = createCustomElement(AlertComponent, { injector: this.injector});
customElements.define('my-alert', alertElement);
}
}
- 这是我的按钮组件:
import {
Input,
Component,
ViewEncapsulation,
EventEmitter,
Output
} from '@angular/core';
@Component({
selector: 'custom-button',
template: `<button (click)="handleClick()">{{label}}</button>`,
styles: [
`
button {
border: solid 3px;
padding: 8px 10px;
background: #bada55;
font-size: 20px;
}
`
],
encapsulation: ViewEncapsulation.Native
})
export class ButtonComponent {
@Input() label = 'default label';
@Output() action = new EventEmitter<number>();
private clicksCt = 0;
handleClick() {
this.clicksCt++;
this.action.emit(this.clicksCt);
}
}
- 这是我的警报组件:
import { Component, Input, OnInit } from '@angular/core';
@Component({
selector: 'alert-message',
template: '<div>Alert Message: {{message}}</div>',
styles: [
`
div {
border: 1px solid #885800;
background-color: #ffcd3f;
padding: 10px;
color: red;
margin:10px;
font-family: Arial;
}
`]
})
export class AlertComponent {
@Input () message: string;
}
- 在 angular.json 中构建配置:
"build": {
"builder": "@angular-devkit/build-angular:browser",
"options": {
"outputPath": "dist",
"index": "src/index.html",
"main": "src/main.ts",
"polyfills": "src/polyfills.ts",
"tsConfig": "src/tsconfig.app.json",
"assets": ["src/favicon.ico", "src/assets"],
"styles": ["src/styles.css"],
"scripts": [
{
"input":
"node_modules/document-register-element/build/document-register-element.js"
}
]
},
"configurations": {
"production": {
"fileReplacements": [
{
"replace": "src/environments/environment.ts",
"with": "src/environments/environment.prod.ts"
}
],
"optimization": true,
"outputHashing": "all",
"sourceMap": false,
"extractCss": true,
"namedChunks": false,
"aot": true,
"extractLicenses": true,
"vendorChunk": false,
"buildOptimizer": true
}
}
},
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "angular6-elements:build"
},
"configurations": {
"production": {
"browserTarget": "angular6-elements:build:production"
}
}
},
"extract-i18n": {
"builder": "@angular-devkit/build-angular:extract-i18n",
"options": {
"browserTarget": "angular6-elements:build"
}
}
- 构建后,我将
runtime, polyfills, script
js 文件连接成单个脚本文件并导出elements.js
包含自定义元素(可选:gzip 那些文件)使用 http-server deploy --gzip 服务它
"scripts": {
"ng": "ng",
"start": "ng serve",
"build": "ng build --prod --output-hashing=none",
"package": "npm run package-base && npm run package-elements",
"package-base": "cat dist/{runtime,polyfills,scripts}.js | gzip > deploy/script.js.gz",
"package-elements": "cat dist/main.js | gzip > deploy/elements.js.gz",
"serve": "http-server deploy --gzip",
"test": "ng test",
"lint": "ng lint",
"e2e": "ng e2e"
}
- 最后,我在 index.html 中包含
script.js
and elements.js
(在部署目录中)以告诉浏览器有关自定义元素的信息。现在 my-button 和 my-alert 可以包含在 index.html 中。在此示例中,按钮在加载时显示,并在单击按钮时动态添加警报消息(带有计数器编号)。这是代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Custom Button Test Page</title>
<script src="script.js"></script>
<script src="elements.js"></script>
</head>
<body>
<my-button label="Show Alert Message!"></my-button>
<p></p>
<div id="message-container"></div>
<script>
const button = document.querySelector('my-button');
const msgContainer = document.querySelector('#message-container');
button.addEventListener('action', (event) => {
console.log(`"action" emitted: ${event.detail}`);
button.setAttribute("label", "Show Next Alert Message!");
msgContainer.innerHTML += `<my-alert message="Here is a message #${event.detail} created dynamically using ng elements!!!"></my-alert>`;
});
</script>
</body>
</html>
这是我的git repo的链接
希望这会有所帮助!
谢谢。