带有@Component()装饰器的TypeScript类是Angular组件中非常重要的一部分。常用的属性包括以下选择器:CSS选择器,用于定义如何使用模板使用组件模板或templateUrl:HTML模板样式或styleUrls:一组可选的CSS样式和一些不太常用的属性,我们来看看他们。如何使用changeDetection:@Component({selector:'app-child',templateUrl:'./child.component.html',styleUrls:['./child.component.scss'],changeDetection:ChangeDetectionStrategy.OnPush})changeDetection用于定义当前组件的变更检测策略。当组件被实例化时,Angular会创建一个变化检测器,它负责传播组件每个绑定值的变化。它在源码中的值是:changeDetection?:ChangeDetectionStrategy,我们来看看ChangeDetectionStrategy在源码中是怎么定义的。exportdeclareenumChangeDetectionStrategy{OnPush=0,Default=1}Default:变更策略为CheckAlways,默认值。对此无话可说。它总是被检测到。即使组件中的属性和@Input属性没有变化,OnPush也会不断检测到变化:变化策略是CheckOnce(按需)。使用ChangeDetectionStrategy.OnPush也是一种优化性能的方法。毕竟是按需检测,不会一直检测,但是使用也是有严格条件的,不然一不小心就会出现bug。如果业务满足以下条件,可以放心使用:组件的视图变化只依赖于@Input属性的变化。如果有一个依赖于组件本身的属性,当@Input属性是非对象时不能使用它,或者当它是对象时每个@Input属性都不能使用。更改是更改对象本身的方式(例如:obj=xxx),而不是更改引用的方式(例如:obj.propertyName=xxx)。如果@Input属性的变化是为了改变引用方法,或者你想触发视图检测变化,你也可以使用ChangeDetectorRef来手动触发变化。注意:Angular每次做变更检测时,组件树都是从上到下的。如果父组件设置为OnPush,就会按照这个策略检测父组件和它的子组件。此时子组件即使设置为Default也是无效的。并且因为父组件是OnPush,所以即使传递给子组件的属性发生变化,也不会更新到子组件(因为视图不会重新渲染)。使用时必须慎重考虑。哈哈,感觉说多了,changeDetection可以单独写一篇文章,如果大家需要了解,我会单独开一篇文章。嗯,下一篇~viewProviders中提到需要了解依赖注入,但是关于DI要学的东西很多,值得单独说明。本章的重点不是DI,就不多说了。源码中viewProviders的取值是:viewProviders?:Provider[];意思是定义一组只在view中可用的Provider对象注意:前提是对象没有注入到根模块,或者组件所在的模块,否则定义viewProviders是没有意义的,as下面我们有一个ServiceDemoservice@Injectable()//注意这里不能加{providedIn:'root'},否则会被注入到根模块中,exportclassServiceDemo{...}可以到处使用。我们把ServiceDemo加入到ChildComponent组件的viewProviders中,ServiceDemo既没有注入到根模块,也没有注入到ChildComponent所在的模块@Component({selector:'app-child',templateUrl:'./child.component.html',styleUrls:['./child.component.scss'],viewProviders:[ServiceDemo]})exportclassChildComponentimplementsOnInit{...}我们只能在ChildComponent的视图中使用ServiceDemo的属性或方法,如果在组件,将报错。供应商与上述有关。如果我们想在ChildComponent的视图和组件中使用ServiceDemo的属性或方法,或者只在组件中使用它们,我们应该将它们添加到提供者中,如下:@Component({selector:'app-child',templateUrl:'./child.component.html',styleUrls:['./child.component.scss'],providers:[ServiceDemo]})exportclassChildComponentimplementsOnInit{...}使用viewProviders或providers,目的仅将提供者对象注入到某个组件或组件视图中。这样的provider对象必须是小范围使用的封装对象,以免注入根模块影响首屏加载。encapsulation用于定义Component的模板和样式封装选项。源码中encapsulation的值是encapsulation?:ViewEncapsulation,我们看看ViewEncapsulation是怎么定义的。exportdeclareenumViewEncapsulation{Emulated=0,//DefaultNative=1,//ObsoleteNone=2,ShadowDom=3}Emulated:这是默认选项。它会在Host元素上添加_nghost-xxx-xxx,在非Host元素上添加_ngcontent-xxx-xxx属性来模拟原生选择器,用于替换class和id,使样式isolatedcomponent不影响外部,组件内部定义的样式只作用于这个组件。
