Angular中的: host 和 ::ng-deep

Angular中的: host 和 ::ng-deep_第1张图片

现在的前端开发都是单页面组件化模式, 也是就一个项目就一个页面, 通过ruter来切换组件, angular也不例外。

而每个组件都有他们自己的样式,虽然每个组件都有自己的样式,但是最终都会打包到一起,那么,问题来了,组件之间的样式会相互影响吗。

我们新建一个项目my-app,在这个项目的src目录下有一个app组件,这个组件就是项目的根组件,我们把它当作父组件用,在app.component.ts里写上这些代码

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    

我是父组件

`, styles: [''] }) export class AppComponent { }

父组件有了

我们再新建两个子组件a.component.ts和b.component.ts,也分别在ts文件里写上这些代码

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-a',
  template: `
    

我是子组件 a

`, styles: [''] }) export class AComponent implements OnInit { constructor() { } ngOnInit(): void { } }

------------------------------------------------------------------------------

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-b',
  template: `
    

我是子组件 b

`, styles: [''] }) export class BComponent implements OnInit { constructor() { } ngOnInit(): void { } }

再把他们用到父组件app中

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    

我是父组件

`, styles: [''] }) export class AppComponent { }

启动项目,打开浏览器,页面上是这样子的

Angular中的: host 和 ::ng-deep_第2张图片

现在我在父组件的styles里给p标签加上样式

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    

我是父组件

`, styles: ['p { color: red; }'] }) export class AppComponent { }

现在页面是这样的

Angular中的: host 和 ::ng-deep_第3张图片

所以,组件之间的样式不会相互影响,为什么?

我们按f12打开控制台,审查下元素看看

Angular中的: host 和 ::ng-deep_第4张图片

可以看到每个组件的元素都被动态的添加了一个属性,每个组件都不一样

再看下父组件里p元素的样式

 

可以看到选择器后面被动态的加了个属性选择器,而这个属性只有父组件里的元素有,这样就不会影响到别的组件了。

Angular就是这样给每个组件的元素动态的加上独有的属性,然后给这个组件的选择器后面也动态的加上这个独有属性选择器,而每个组件的动态属性都不一样,这样选择器就只会选到自己组件的dom元素,从而防止组件的样式污染,让它们互不影响

那么angular里的:host 是做什么的,:host 是让选择器只选择自己组件的dom

我现在给父组件的p标签选择器前面加上一个:host

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    

我是父组件

`, styles: [':host p { color: red; }'] }) export class AppComponent { }

再来看下样式

可以看到 :host 会给选择器的前面加上一个自己组件的动态属性的属性选择器

这个动态属性只有当前这个组件有,从而保证选择器只能作用于自己的组件

接下来是::ng-deep了

把父组件里的:host 换成 ::ng-deep

import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    

我是父组件

`, styles: ['::ng-deep p { color: red; }'] }) export class AppComponent { }

然后页面变成这样 

Angular中的: host 和 ::ng-deep_第5张图片

子组件被影响了,为什么我在父组件的样式会影响子组件,不是互不影响吗?因为加了::ng-deep

我们看下页面上p元素的样式

 

可以看到加了::ng-deep后,选择器后面的属性选择器没了,这样就是导致这个样式可以影响到别的组件,只要它是p标签, 因为都是在同一个页面

现在我们明白了:host 和 ::ng-deep 的作用,那么它们再实际情况下是怎么使用的?

实际情况下就是这两个基本是一起配合使用,在一些使用了第三方组件,又想修改第三方组件里元素的样式时, 或者是项目里的通用组件,想在某个使用它的组件里单独修改它的样式,而不影响别的组件

我们现在新建一个通用组件c.component.ts

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-c',
  template: `
我是通用组件c
`, styles: ['div { height: 200px; width: 200px; background-color: blue; }'] }) export class CComponent implements OnInit { constructor() { } ngOnInit(): void { } }

通用组件c就是一个蓝色方块

我们把他用到a和b组件中

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-a',
  template: `
    

我是子组件 a

`, styles: [''] }) export class AComponent implements OnInit { constructor() { } ngOnInit(): void { } }

------------------------------------------------------------------------------

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-b',
  template: `
    

我是子组件 b

`, styles: [''] }) export class BComponent implements OnInit { constructor() { } ngOnInit(): void { } }

现在页面上是这样的

Angular中的: host 和 ::ng-deep_第6张图片

我现在想在a组件里把方块c改成绿色,而又不影响b组件里的方块c,这个时候就要用:host和 ::ng-deep 了

在组件a的styles里加上这些样式

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-a',
  template: `
    

我是子组件 a

`, styles: [':host ::ng-deep div { background-color: green !important; }'] }) export class AComponent implements OnInit { constructor() { } ngOnInit(): void { } }

 页面如下

Angular中的: host 和 ::ng-deep_第7张图片

成功了

看下组件a里的c方块的样式

Angular中的: host 和 ::ng-deep_第8张图片

:host 在前面加了个本组件的动态属性的属性选择器,确保样式只生效于本组件和他的子组件,::ng-deep 把选择器后面的属性选择器去掉了,这样就能作用别的组件了。

组合在一起就是只有本组件和本组件的子组件里的div才能被选择到, 这样既能控制范围,又能影响到子组件

同理,第三方组件也是类似的用法

这就是我分享的一些关于 :host 和 ::ng-deep 的简单用法

你可能感兴趣的:(Angular,angular,typescript)