当前位置: 首页 > 编程日记 > 正文

深入解析Angular Component的源码示例

本篇文章主要介绍了剖析Angular Component的源码示例,写的十分的全面细致,具有一定的参考价值,对此有需要的朋友可以参考学习下。如有不足之处,欢迎批评指正。

Web Component

定义

W3C为统一组件化标准方式,提出Web Component的标准。

每个组件包含自己的html、css、js代码。
Web Component标准包括以下四个重要的概念:
1.Custom Elements(自定义标签):可以创建自定义 HTML 标记和元素;
2.HTML Templates(HTML模版):使用 <template> 标签去预定义一些内容,但并不加载至页面,而是使用 JS 代码去初始化它;
3.Shadow DOM(虚拟DOM):可以创建完全独立与其他元素的DOM子树;
4.HTML Imports(HTML导入):一种在 HTML 文档中引入其他 HTML 文档的方法,<link rel="import" href="example.html" rel="external nofollow" />。

概括来说就是,可以创建自定义标签来引入组件是前端组件化的基础,在页面引用 HTML 文件和 HTML 模板是用于支撑编写组件视图和组件资源管理,而 Shadow DOM 则是隔离组件间代码的冲突和影响。

示例

定义hello-component

<template id="hello-template"><style>h1 {color: red;}</style><h1>Hello Web Component!</h1>
</template><script>// 指向导入文档,即本例的index.htmlvar indexDoc = document;// 指向被导入文档,即当前文档hello.htmlvar helloDoc = (indexDoc._currentScript || indexDoc.currentScript).ownerDocument;// 获得上面的模板var tmpl = helloDoc.querySelector('#hello-template');// 创建一个新元素的原型,继承自HTMLElementvar HelloProto = Object.create(HTMLElement.prototype);// 设置 Shadow DOM 并将模板的内容克隆进去HelloProto.createdCallback = function() {var root = this.createShadowRoot();root.appendChild(indexDoc.importNode(tmpl.content, true));};// 注册新元素var hello = indexDoc.registerElement('hello-component', {prototype: HelloProto});
</script>

使用hello-component

<!DOCTYPE html>
<html lang="zh-cn">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-COMPATIBLE" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><meta name="author" content="赖祥燃, laixiangran@163.com, http://www.laixiangran.cn"/><title>Web Component</title><!--导入自定义组件--><link rel="import" href="hello.html" rel="external nofollow" >
</head>
<body><!--自定义标签--><hello-component></hello-component>
</body>
</html>

从以上代码可看到,hello.html 为按标准定义的组件(名称为 hello-component ),在这个组件中有自己的结构、样式及逻辑,然后在 index.html 中引入该组件文件,即可像普通标签一样使用。

Angular Component

Angular Component属于指令的一种,可以理解为拥有模板的指令。其它两种是属性型指令和结构型指令。
基本组成

@Component({selector: 'demo-component',template: 'Demo Component'
})
export class DemoComponent {}
  • 组件装饰器:每个组件类必须用@component进行装饰才能成为Angular组件。
  • 组件元数据:组件元数据:selector、template等,下文将着重讲解每个元数据的含义。
  • 组件类:组件实际上也是一个普通的类,组件的逻辑都在组件类里定义并实现。
  • 组件模板:每个组件都会关联一个模板,这个模板最终会渲染到页面上,页面上这个DOM元素就是此组件实例的宿主元素。

组件元数据

自身元数据属性

从 core/Directive 继承

几种元数据详解

以下几种元数据的等价写法会比元数据设置更简洁易懂,所以一般推荐的是等价写法。

inputs

@Component({selector: 'demo-component',inputs: ['param']
})
export class DemoComponent {param: any;
}

等价于:

@Component({selector: 'demo-component'
})
export class DemoComponent {@Input() param: any;
}

outputs

@Component({selector: 'demo-component',outputs: ['ready']
})
export class DemoComponent {ready = new eventEmitter<false>();
}

等价于:

@Component({selector: 'demo-component'
})
export class DemoComponent {@Output() ready = new eventEmitter<false>();
}

host

@Component({selector: 'demo-component',host: {'(click)': 'onClick($event.target)', // 事件'role': 'nav', // 属性'[class.pressed]': 'isPressed', // 类}
})
export class DemoComponent {isPressed: boolean = true;onClick(elem: HTMLElement) {console.log(elem);}
}

等价于:

@Component({selector: 'demo-component'
})
export class DemoComponent {@HostBinding('attr.role') role = 'nav';@HostBinding('class.pressed') isPressed: boolean = true;@HostListener('click', ['$event.target'])onClick(elem: HTMLElement) {console.log(elem);}
}

queries - 视图查询

@Component({selector: 'demo-component',template: `<input #theInput type='text' /><div>Demo Component</div>`,queries: {theInput: new ViewChild('theInput')}
})
export class DemoComponent {theInput: ElementRef;
}

等价于:

@Component({selector: 'demo-component',template: `<input #theInput type='text' /><div>Demo Component</div>`
})
export class DemoComponent {@ViewChild('theInput') theInput: ElementRef;
}

queries - 内容查询

<my-list><li *ngFor="let item of items;">{{item}}</li>
</my-list>@Directive({selector: 'li'
})
export class ListItem {}@Component({selector: 'my-list',template: `<ul><ng-content></ng-content></ul>`,queries: {items: new ContentChild(ListItem)}
})
export class MyListComponent {items: QueryList<ListItem>;
}

等价于:

@Component({selector: 'my-list',template: `<ul><ng-content></ng-content></ul>`
})
export class MyListComponent {@ContentChild(ListItem) items: QueryList<ListItem>;
}

styleUrls、styles

styleUrls和styles允许同时指定。
优先级:模板内联样式 > styleUrls > styles。
建议:使用styleUrls引用外部样式表文件,这样代码结构相比styles更清晰、更易于管理。同理,模板推荐使用templateUrl引用模板文件。

changeDetection

ChangeDetectionStrategy.Default:组件的每次变化监测都会检查其内部的所有数据(引用对象也会深度遍历),以此得到前后的数据变化。
ChangeDetectionStrategy.OnPush:组件的变化监测只检查输入属性(即@Input修饰的变量)的值是否发生变化,当这个值为引用类型(Object,Array等)时,则只对比该值的引用。
显然,OnPush策略相比Default降低了变化监测的复杂度,很好地提升了变化监测的性能。如果组件的更新只依赖输入属性的值,那么在该组件上使用OnPush策略是一个很好的选择。

encapsulation

ViewEncapsulation.None:无 Shadow DOM,并且也无样式包装。
ViewEncapsulation.Emulated:无 Shadow DOM,但是通过Angular提供的样式包装机制来模拟组件的独立性,使得组件的样式不受外部影响,这是Angular的默认设置。
ViewEncapsulation.Native:使用原生的 Shadow DOM 特性。

生命周期

当Angular使用构造函数新建组件后,就会按下面的顺序在特定时刻调用这些生命周期钩子方法:

结语

感谢您的观看,如有不足之处,欢迎批评指正。

相关文章:

VS2017 cout 不明确

各种头文件没问题。直接声明名称空间 using namespace std&#xff1b; 解决方法&#xff1a; 然后把using namespace std;这句给注释掉&#xff0c;等出现错误提示&#xff0c;在取消注释&#xff0c;然后就好了

google breakpad native crash分析工具

一. BreakPad简介Google breakpad是一个跨平台的崩溃转储和分析框架和工具集合。Breakpad由三个主要组件&#xff1a;client&#xff0c;以library的形式内置在你的应用中&#xff0c;当崩溃发生时写 minidump文件symbol dumper, 读取由编译器生成的调试信息&#xff08;debugg…

Java基础教程(15)--枚举类型

枚举类型定义了一个枚举值的列表&#xff0c;每个值是一个标识符。例如&#xff0c;下面的语句声明了一个枚举类型&#xff0c;用来表示星期的可能情况&#xff1a; public enum Day {SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY } 实际上&#xff0c;这个…

基于AOA协议的android USB通信

摘 要&#xff1a;AOA协议是Google公司推出的用于实现Android设备与外围设备之间USB通信的协议。该协议拓展了Android设备USB接口的功能&#xff0c;为基于Android系统的智能设备应用于数据采集和设备控制领域提供了条件。介绍了Android系统下USB通信的两种模式&#xff0c;并给…

Linux下使用ssh动态验证码登陆机器

ssh动态验证码登录机器Google Authenticator是一个动态验证码程序&#xff0c;兼容各种智能手机平板设备&#xff0c;可以用来做各种帐号的二次验证&#xff0c;增加帐号的安全性。SSH是Linux系统的最重要防线之一&#xff0c;为了防止密码泄露或者被爆破&#xff0c;可以使用G…

【C++】枚举类型应用

运行环境&#xff1a;VS2017 可以参考&#xff1a;【C】枚举类型 医院内科有A&#xff0c;B&#xff0c;C&#xff0c;D&#xff0c;E&#xff0c;F&#xff0c;G共七位医生&#xff0c;每人在一周内要值一次夜班&#xff0c;排班的要求&#xff1a; &#xff08;1&#xff…

量子力学又一突破,中国科学家首次实现量子纠缠态自检验

这也是国际上首个具有“高可靠、抗干扰”特性的纠缠态自检验实验。 最近&#xff0c;量子力学领域又传来好消息&#xff0c;中国科学技术大学的郭光灿院士团队在实验中首次实现了量子纠缠态的自检验&#xff0c;推动了自检验在各种量子信息过程中的基础发展。 何为量子纠缠&a…

awk命令中执行多条shell命令

awk中使用的shell命令&#xff0c;有2种方法&#xff1a;一。使用system&#xff08;&#xff09;二。使用print cmd | “/bin/bash”http://www.gnu.org/software/gawk/manual/gawk.html#I_002fO-Functions一。使用所以system&#xff08;&#xff09;awk程序中我们可以使用sy…

LAMP高级环境实战

LAMP架构应用实战介绍LAMP指的Linux&#xff08;操作系统&#xff09;、Apache&#xff08;HTTP 服务器&#xff09;&#xff0c;MySQL&#xff08;数据库软件&#xff09; 和PHP&#xff08;有时也是指Perl或Python&#xff09; 的第一个字母&#xff0c;一般用来建立web 服务…

【C++】用类来处理排序问题

运行环境&#xff1a;VS2017 由小到大排序 可以看出在主函数中所做的事&#xff1a; &#xff08;1&#xff09;定义对象。 &#xff08;2&#xff09;向各对象发出“消息”&#xff0c;通知各对象完成有关任务。即调用有关对象的成员函数&#xff0c;去完成相应的操作。 …

winform 弹出窗体位置设定

[转]https://www.cnblogs.com/liushenglin/p/5350641.html 一、C#中弹出窗口位置 加入命名空间using System.Drawing和using System.Windows.Forms假定窗口名为form1,则 form1.StartPosition FormStartPosition.CenterScreen;窗体位置在屏幕中间form1.StartPosition FormSta…

pkg-config工具在实际工程中的用法

在如今这个开源的环境里&#xff0c;想要开发某个功能&#xff0c;我们都会下意识的上网搜索有没有开源库&#xff0c;如果有开源库&#xff0c;那么好&#xff0c;下载下来给它编译好&#xff0c;使用。但是在使用过程中&#xff0c;你是否遇到不知如何将第三方库编译&#xf…

linux中pipe

调用pipe函数时在内核中开辟一块缓冲区(称为管道)用于通信,它有一个读端一个写端,然后通过filedes参数传出给用户程序两个文件描述符,filedes[0]指向管道的读端,filedes[1]指向管道的写端(很好记就像0是标准输入1是标准输出一样)。所以管道在用户程序看起来就像一个打开的文通r…

【C++】利用构造函数对类对象进行初始化

运行环境&#xff1a;VS2017 一、对象的初始化 每一个对象都应当在它建立之时就有就有确定的内容&#xff0c;否则就会失去对象的意义。 class Time {int hour 0;int min 0;int sec 0; }; 这种是错误的&#xff0c;类并不是一个实体&#xff0c;并不占储存空间&#xff…

自定义Chrome浏览器

一、全局 自用备份&#xff0c;窗体透明化、要添加对应网站的窗体class到对应的位置 /*主页背景*/ /*https://images.cnblogs.com/cnblogs_com/AardWolf/1350846/o_5900399dcdcbd.jpg*/ /*https://ws4.sinaimg.cn/large/0072Vf1pgy1foxkfzphb2j31hc0u0gvv.jpg*/body { backgrou…

ubuntu添加sudo权限

使用如下命令可以添加到用户组&#xff08;也可是超级用户组&#xff09;。 命令如下&#xff1a; sudo usermod -aG 超级用户组名 用户名 例子&#xff1a;sudo usermod -aG sudo username 其中a:表示添加&#xff0c;G&#xff1a;指定组名第二种方法是直接修改&#xff0c…

File.separator

报告“No such file or diretory ”的异常&#xff0c;上传不了。后来发现是文件路径的问题。模拟测试环境是windowstomcat&#xff0c;而正式的的环境是linuxtomcat&#xff0c;文件路径的分隔符在windows系统和linux系统中是不一样。 比如说要在temp目录下建立一个test.txt文…

【C++】对象数组

运行环境&#xff1a;VS2017 对象数组&#xff1a;每个元素都是同类的对象 如果构造函数只有一个参数&#xff0c;在定义数组时可以直接在等号后面的花括号内提供实参。 Student stud[3]{60,70,80}; 如果构造函数有多个参数&#xff0c;则不能用在定义数组时直接提供所有实…

C# 算法系列一基本数据结构

一、简介 作为一个程序员,算法是一个永远都绕不过去的话题,虽然在大学里参加过ACM的比赛,没记错的话,浙江赛区倒数第二,后来不知怎么的,就不在Care他了,但是现在后悔了,非常的后悔!!!如果当时好好学算法的话,现在去理解一些高深的框架可能会很easy,现在随着C#基础和Web技能的提…

git管理大项目或者大文件

git 是追踪代码库演进的最佳选择&#xff0c;并且它能让你与你的同事间高效协作。当你想要追踪的库非常巨大时会发生什么&#xff1f;在这篇文章里&#xff0c;我会尝试着给你一些想法和技巧来恰当地处理不同种类的大仓库。两种大代码库如果仔细想想&#xff0c;大概会有两种导…

window下java开发环境安装

首先请去Java的官网上下载&#xff0c;最好下载最新版本地址&#xff1a;http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 如图&#xff0c;点击下载java platform&#xff08;JDK&#xff09;,然后选择接受接受协议&#xff08;Accept …

【ACM】蛇形填数

先判断&#xff0c;再移动&#xff0c;而不是发现越界了再退回来。 #include "stdio.h" #include "string.h" #define maxn 20 int a[maxn][maxn]; int main() {int n, x, y, tot 0;scanf_s("%d", &n);memset(a, 0, sizeof(a));tot a[x …

Mybatis中Oracle和Mysql的Count字段问题

Mybatis中Oracle和Mysql的Count字段问题 我们在进行项目开发时经常会碰到查询总数的问题&#xff0c;所以我们直接是用select count(1) from table来进行查询。那么在Mybatis通常情况下我们是这么写的 <select id"testCount" resultType"int">select…

为什么free()时不需要传指针大小

malloc()和free()是c中两个非常基本的函数&#xff0c;但这种最基本的东西往往都是特别复杂的。malloc和free的原形如下&#xff1a;void *malloc(unsigned int num_bytes); void free(void *ptr);在c的标准中并没有定义这两个函数的具体实现&#xff0c;在我们最常用的gcc中&a…

redis cluster 安装配置

一、redis集群安装配置1、下载redis源码包并下载wget http://download.redis.io/releases/redis-3.0.7.tar.gz $ tar xzf redis-3.0.7.tar.gz $ cd redis-3.0.7 yum -y install gcc gcc-c libstdc-devel #解决相关依赖关系$ make && make install 因我们安装redis 集…

【ACM】汉诺塔

https://blog.csdn.net/xueerfei008/article/details/9904681

什么是机器人底盘 答案在这里!

机器人底盘承载了机器人本身的定位、导航及避障等基本功能&#xff0c;可帮助机器人实现智能行走&#xff0c;以思岚科技的ZEUS为例&#xff0c;内置SLAMWARE高性能自主定位导航模块&#xff0c;用户可根据实际需要搭载不同的应用&#xff0c;可广泛适用于餐厅、商场、银行、办…

嵌入式linux内存使用和性能优化

这本书有两个关切点&#xff1a;系统内存(用户层)和性能优化。 这本书和Brendan Gregg的《Systems Performance》相比&#xff0c;无论是技术层次还是更高的理论都有较大差距。但是这不影响&#xff0c;快速花点时间简单过一遍。 然后在对《Systems Performance》进行详细的学…

【算法导论】插入排序

循环不变式 在数学上阐述了通过循环&#xff08;迭代&#xff0c;递归&#xff09;去计算一个累计的目标值的正确性。 关于循环不变式&#xff0c;我们必须要证明三条性质&#xff1a; 初始化&#xff1a;循环第一次迭代之前&#xff0c;它为真。保持&#xff1a;如果循环的…