![Angular Tutorial](/angular/images/angular-mini-logo.jpg)
- Angular 教程
- Angular - 首页
- Angular - 概述
- Angular - 特性
- Angular - 优点与缺点
- Angular 基础
- Angular - 环境搭建
- Angular - 第一个应用
- Angular - MVC 架构
- Angular 组件
- Angular - 组件
- Angular - 组件生命周期
- Angular - 视图封装
- Angular - 组件交互
- Angular - 组件样式
- Angular - 嵌套组件
- Angular - 内容投影
- Angular - 动态组件
- Angular - 元素
- Angular 模板
- Angular - 模板
- Angular - 文本插值
- Angular - 模板语句
- Angular - 模板中的变量
- Angular - SVG 作为模板
- Angular 数据绑定
- Angular - 数据绑定及类型
- Angular - 数据绑定
- Angular - 事件绑定
- Angular - 属性绑定
- Angular - 属性绑定
- Angular - 类和样式绑定
- Angular 指令
- Angular - 指令
- Angular - 内置指令
- Angular 管道
- Angular - 管道
- Angular - 使用管道转换数据
- Angular 依赖注入
- Angular - 依赖注入
- Angular HTTP 客户端编程
- Angular - 服务
- Angular - HTTP 客户端
- Angular - 请求
- Angular - 响应
- Angular - GET 请求
- Angular - PUT 请求
- Angular - DELETE 请求
- Angular - JSON-P
- Angular - 使用 HTTP 进行 CRUD 操作
- Angular 路由
- Angular - 路由
- Angular - 导航
- Angular - Angular Material
- Angular 动画
- Angular - 动画
- Angular 表单
- Angular - 表单
- Angular - 表单验证
- Angular Service Workers & PWA
- Angular - Service Workers & PWA
- Angular 测试
- Angular - 测试概述
- Angular NgModule
- Angular - 模块介绍
- Angular 高级
- Angular - 身份验证与授权
- Angular - 国际化
- Angular - 可访问性
- Angular - Web Workers
- Angular - 服务器端渲染
- Angular - Ivy 编译器
- Angular - 使用 Bazel 构建
- Angular - 向后兼容性
- Angular - 响应式编程
- Angular - 指令和组件之间共享数据
- Angular 工具
- Angular - CLI
- Angular 其他
- Angular - 第三方控件
- Angular - 配置
- Angular - 显示数据
- Angular - 装饰器和元数据
- Angular - 基本示例
- Angular - 错误处理
- Angular - 测试和项目构建
- Angular - 生命周期钩子
- Angular - 用户输入
- Angular - 最新动态?
- Angular 有用资源
- Angular - 快速指南
- Angular - 有用资源
- Angular - 讨论
Angular - 元素
Angular 提供了一种简单有效的方法来创建 Web 组件。Web 组件是原生 HTML 规范中提供的自定义 HTML 元素,用于扩展 HTML 文档的功能/标签。它可以通过 JavaScript 创建,并可在 HTML 文档中使用。JavaScript 具有创建自定义 HTML 元素的特殊方法。
使用 JavaScript 创建自定义 HTML 元素是一个冗长的过程,开发人员需要了解自定义 HTML 元素的内部机制和 Shadow DOM 概念。Angular 通过将 Angular 组件转换为 Web 组件来简化此过程,只需对组件类进行最小的更改。
让我们在本节学习如何创建自定义 HTML 组件。
创建自定义组件的步骤
步骤 1:使用 Angular CLI 创建一个普通的 Angular 应用。
ng new my-app
在此,如果 CLI 询问是否包含路由模块,请选择“否”,因为在此场景中我们不需要它。
步骤 2:使用 Angular CLI 创建组件。跳过将组件导入模块。
ng generate component my-component --skip-import
步骤 3:在 @Component 装饰器中添加 standalone 属性,并将其设置为 true。顾名思义,该组件将在构建应用程序时与必要的 Angular 代码捆绑在一起,以便该组件可以在任何 HTML 文档中工作,而无需 Angular 引导代码。
@Component({ // ... standalone: true, }) export class MyCustomComponent { // ... }
步骤 4:在 @Component 装饰器中添加 encapsulation 选项,并将其设置为 ViewEncapsulation.ShadowDom。ShadowDom 选项启用 HTML 原生 ShadowDom 概念,以保留组件的样式,而不会泄漏到 HTML 文档的其他部分。
@Component({ // ... encapsulation: ViewEncapsulation.ShadowDom }) export class MyCustomComponent { // ... }
步骤 5:接下来,根据规范开发组件。
步骤 6:接下来,安装 Angular 团队提供的 @angular/elements 模块。@angular/elements 模块提供将 Angular 组件创建为自定义 HTML 元素的选项。
ng add @angular/elements
步骤 7:接下来,打开 main.ts 并移除所有样板代码。
步骤 8:接下来,从 @angular/platform-browser 导入 createApplication。createApplication 将引导 Angular 应用程序。
import { createApplication } from '@angular/platform-browser';
步骤 9:接下来,从 @angular/elements 模块导入 createCustomElement。createCustomElement 将用于从 Angular 组件创建自定义 HTML 元素。
import { createCustomElement } from '@angular/elements';
步骤 10:接下来,使用 createAppliation() 方法创建应用程序,方法是输入提供程序和回调方法。回调方法将用于从 Angular 组件创建自定义 HTML 元素。
createApplication({ providers: [] }).then((appRef) => { // ... });
步骤 11:实现回调方法,并使用 createCustomElement() 方法创建自定义元素。createCustomElement 接受要转换的组件和应用程序的注入器。我们可以从 createApplication() 方法返回的应用程序引用中获取注入器。
createApplication({ providers: [] }).then((appRef) => { const myCustomComponent = createCustomElement( MyCustomComponent, { injector: appRef.injector } ); });
步骤 12:接下来,使用 JavaScript 原生方法 customElements.define() 方法注册创建的自定义组件。
createApplication({ providers: [] }).then((appRef) => { const myCustomComponent = createCustomElement( MyCustomComponent, { injector: appRef.injector } ); customElements.define('my-custom-comp', myCustomComponent); });
步骤 13:接下来,使用 Angular CLI 的 build 命令构建应用程序。
ng build --configuration=production
步骤 14:构建完成后,输出文件位于 dist/my-custom-component 文件夹中。它包含以下文件(类似文件)以及 index.html 文件。
- main.bbeaed7335f8e75c.js
- styles.ef46db3751d8e999.css
- polyfills.b270da5a29e91679.js
- runtime.5f19eeacd93d937b.js
步骤 15:使用新创建的组件更新 index 文件,并检查输出是否正确。如果组件需要更改,请根据需要更新 Angular 组件并重新构建应用程序。
<!doctype html> <html lang="en" data-critters-container> <head> <meta charset="utf-8"> <title>MyWebComponent</title> <base href="/"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/x-icon" href="favicon.ico"> <link rel="stylesheet" href="styles.ef46db3751d8e999.css"> </head> <body> <!-- add you custom component --> <script src="runtime.5f19eeacd93d937b.js" type="module"></script><script src="polyfills.b270da5a29e91679.js" type="module"></script><script src="main.bbeaed7335f8e75c.js" type="module"></script> </body> </html>
工作示例
让我们创建一个显示员工信息的组件(例如 EmpCard),并将其转换为自定义 HTML 元素。
步骤 1:使用 Angular CLI 创建一个 Angular 应用程序 emp-card-web-component。
$ ng new emp-card-web-component ? Would you like to add Angular routing? No ? Which stylesheet format would you like to use? CSS CREATE emp-card-web-component/README.md (1073 bytes) CREATE emp-card-web-component/.editorconfig (274 bytes) CREATE emp-card-web-component/.gitignore (548 bytes) CREATE emp-card-web-component/angular.json (2780 bytes) CREATE emp-card-web-component/package.json (1053 bytes) CREATE emp-card-web-component/tsconfig.json (901 bytes) CREATE emp-card-web-component/tsconfig.app.json (263 bytes) CREATE emp-card-web-component/tsconfig.spec.json (273 bytes) CREATE emp-card-web-component/.vscode/extensions.json (130 bytes) CREATE emp-card-web-component/.vscode/launch.json (470 bytes) CREATE emp-card-web-component/.vscode/tasks.json (938 bytes) CREATE emp-card-web-component/src/main.ts (214 bytes) CREATE emp-card-web-component/src/favicon.ico (948 bytes) CREATE emp-card-web-component/src/index.html (305 bytes) CREATE emp-card-web-component/src/styles.css (80 bytes) CREATE emp-card-web-component/src/app/app.module.ts (314 bytes) CREATE emp-card-web-component/src/app/app.component.css (0 bytes) CREATE emp-card-web-component/src/app/app.component.html (23083 bytes) CREATE emp-card-web-component/src/app/app.component.spec.ts (940 bytes) CREATE emp-card-web-component/src/app/app.component.ts (226 bytes) CREATE emp-card-web-component/src/assets/.gitkeep (0 bytes) ✔ Packages installed successfully. Directory is already under version control. Skipping initialization of git. ng new my-app
在此,如果 CLI 询问是否包含路由模块,请选择“否”,因为在此场景中我们不需要它。
步骤 2:使用 Angular CLI 创建员工组件。跳过将组件导入模块。
$ ng generate component emp-card --skip-import CREATE src/app/emp-card/emp-card.component.css (0 bytes) CREATE src/app/emp-card/emp-card.component.html (23 bytes) CREATE src/app/emp-card/emp-card.component.spec.ts (567 bytes) CREATE src/app/emp-card/emp-card.component.ts (209 bytes)
步骤 3:在 @Component 装饰器中添加 standalone 属性,并将其设置为 true。顾名思义,该组件将在构建应用程序时与必要的 Angular 代码捆绑在一起,以便该组件可以在任何 HTML 文档中工作,而无需 Angular 引导代码。
@Component({ // ... standalone: true, }) export class EmpCardComponent { // ... }
步骤 4:在 @Component 装饰器中添加 encapsulation 选项,并将其设置为 ViewEncapsulation.ShadowDom。ShadowDom 选项启用 HTML 原生 ShadowDom 概念,以保留组件的样式,而不会泄漏到 HTML 文档的其他部分。
@Component({ // ... encapsulation: ViewEncapsulation.ShadowDom }) export class EmpCardComponent { // ... }
步骤 5:接下来,添加两个输入属性 name 和 role,以在 HTML 元素中提供员工的姓名和角色。
export class EmpCardComponent { @Input() name: string = ''; @Input() role: string = ''; }
步骤 6:组件的完整列表如下:
import { Component, Input, ViewEncapsulation } from '@angular/core'; @Component({ selector: 'app-emp-card', templateUrl: './emp-card.component.html', styleUrls: ['./emp-card.component.css'], standalone: true, encapsulation: ViewEncapsulation.ShadowDom }) export class EmpCardComponent { @Input() name: string = ''; @Input() role: string = ''; }
步骤 7:接下来,打开组件的模板并添加标记以显示员工姓名和角色,如下所示:
<div class="card"> <div class="container"> <h4><b>{{ name }}</b></h4> <p>{{ role }}</p> </div> </div>
步骤 8:接下来,打开组件的样式并添加 CSS 以在员工卡片中显示阴影。
.card { box-shadow: 0 4px 8px 0 rgba(0,0,0,0.2); } .card:hover { box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2); } .container { padding: 2px 16px; max-width: 200px; }
步骤 9:接下来,安装 Angular 团队提供的 @angular/elements 模块。@angular/elements 模块提供将 Angular 组件创建为自定义 HTML 元素的选项。
$ ng add @angular/elements Using package manager: npm ✔ Found compatible package version: @angular/[email protected]. ✔ Package information loaded. The package @angular/[email protected] will be installed and executed. Would you like to proceed? Yes ✔ Packages successfully installed. Package "@angular/elements" was found but does not support schematics.
步骤 10:接下来,打开 main.ts 并移除所有样板代码。
步骤 11:接下来,从 @angular/platform-browser 导入 createApplication。createApplication 将引导 Angular 应用程序。
import { createApplication } from '@angular/platform-browser';
步骤 12:接下来,从 @angular/elements 模块导入 createCustomElement。createCustomElement 将用于从 Angular 组件创建自定义 HTML 元素。
import { createCustomElement } from '@angular/elements';
步骤 13:接下来,导入 EmpCardComponnet 组件,如下所示:
import { EmpCardComponent } from './app/emp-card/emp-card.component'
步骤 14:接下来,使用 createAppliation() 方法创建应用程序,方法是输入提供程序和回调方法。回调方法将用于从 Angular 组件创建自定义 HTML 元素。
createApplication({ providers: [] }).then((appRef) => { // ... });
步骤 15:实现回调方法,并使用 createCustomElement() 方法创建自定义元素。createCustomElement 接受要转换的组件和应用程序的注入器。我们可以从 createApplication() 方法返回的应用程序引用中获取注入器。
createApplication({ providers: [] }).then((appRef) => { const empCard = createCustomElement( EmpCardComponent, { injector: appRef.injector } ); });
步骤 16:接下来,使用 JavaScript 原生方法 customElements.define() 方法注册创建的自定义组件。
createApplication({ providers: [] }).then((appRef) => { const empCard = createCustomElement( EmpCardComponent, { injector: appRef.injector } ); customElements.define('emp-card', empCard); });
步骤 17:main 文件 main.ts 的完整列表如下:
import { AppModule } from './app/app.module'; import { createApplication } from '@angular/platform-browser'; import { createCustomElement } from '@angular/elements'; import { EmpCardComponent } from './app/emp-card/emp-card.component' createApplication({ providers: [] }).then((appRef) => { const empCard = createCustomElement( EmpCardComponent, { injector: appRef.injector } ); customElements.define('emp-card', empCard); });
步骤 18:接下来,使用 Angular CLI 的 build 命令构建应用程序。
ng build --configuration=production ✔ Browser application bundle generation complete. ✔ Copying assets complete. ✔ Index html generation complete. Initial Chunk Files | Names | Raw Size | Estimated Transfer Size main.bbeaed7335f8e75c.js | main | 95.37 kB | 28.59 kB polyfills.b270da5a29e91679.js | polyfills | 33.04 kB | 10.63 kB runtime.5f19eeacd93d937b.js | runtime | 922 bytes | 526 bytes styles.ef46db3751d8e999.css | styles | 0 bytes | - | Initial Total | 129.31 kB | 39.74 kB
步骤 19:构建完成后,输出文件位于 dist/emp-card-web-component 文件夹中。它包含以下文件(类似文件)以及 index.html 文件。
- main.bbeaed7335f8e75c.js
- styles.ef46db3751d8e999.css
- polyfills.b270da5a29e91679.js
- runtime.5f19eeacd93d937b.js
步骤 20:使用新创建的组件更新 index 文件,并检查输出是否正确。
<!doctype html> <html lang="en" data-critters-container> <head> <meta charset="utf-8"> <title>EmpCardWebComponent</title> <base href="/"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="icon" type="image/x-icon" href="favicon.ico"> <link rel="stylesheet" href="styles.ef46db3751d8e999.css"></head> <body> <emp-card name="John" role="Angular developer"></emp-card> <emp-card name="Maria" role="Frontend developer"></emp-card> <script src="runtime.5f19eeacd93d937b.js" type="module"></script><script src="polyfills.b270da5a29e91679.js" type="module"></script><script src="main.bbeaed7335f8e75c.js" type="module"></script> </body> </html>
在这里,我们添加了两个不同员工详细信息的 emp-card 标签。
步骤 21:最后,在 dist/emp-card-web-component 文件夹中运行一个 http 服务器,并在浏览器中检查输出。
![Employee Information](/angular/images/employee-information.jpg)
总结
正如我们所学到的,在 Angular 中创建 Web 组件非常容易。我们只需要像开发普通的 Angular 组件一样开发组件即可。一旦组件的功能开发完毕,我们需要在 main.ts 文件中添加一些引导代码,并构建应用程序以获得必要的自定义 HTNL 元素作为一堆原生 JavaScript。我们可以在任何网站上使用它,而无需 Angular。