Angular中的: host 和 ::ng-deep

本文探讨了Angular中组件样式隔离的机制,通过分析:host和::ng-deep的作用,解释了如何避免样式污染,以及如何在子组件和第三方组件中精确控制样式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

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

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

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

@Component({
  selector: 'app-root',
  template: `
    <p>我是父组件</p>
  `,
  styles: ['']
})
export class AppComponent { }

父组件有了

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

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

@Component({
  selector: 'app-a',
  template: `
    <p>我是子组件 a</p>
  `,
  styles: ['']
})
export class AComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }

}

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

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

@Component({
  selector: 'app-b',
  template: `
    <p>我是子组件 b</p>
  `,
  styles: ['']
})
export class BComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }

}

再把他们用到父组件app中

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

@Component({
  selector: 'app-root',
  template: `
    <p>我是父组件</p>
    <app-a></app-a>
    <app-b><app-b>
  `,
  styles: ['']
})
export class AppComponent { }

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

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

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

@Component({
  selector: 'app-root',
  template: `
    <p>我是父组件</p>
    <app-a></app-a>
    <app-b><app-b>
  `,
  styles: ['p { color: red; }']
})
export class AppComponent { }

现在页面是这样的

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

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

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

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

 

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

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

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

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

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

@Component({
  selector: 'app-root',
  template: `
    <p>我是父组件</p>
    <app-a></app-a>
    <app-b><app-b>
  `,
  styles: [':host p { color: red; }']
})
export class AppComponent { }

再来看下样式

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

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

接下来是::ng-deep了

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

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

@Component({
  selector: 'app-root',
  template: `
    <p>我是父组件</p>
    <app-a></app-a>
    <app-b><app-b>
  `,
  styles: ['::ng-deep p { color: red; }']
})
export class AppComponent { }

然后页面变成这样 

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

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

 

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

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

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

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

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

@Component({
  selector: 'app-c',
  template: `<div>我是通用组件c</div>`,
  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: `
    <p>我是子组件 a</p>
    <app-c></app-c>
  `,
  styles: ['']
})
export class AComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }

}

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

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

@Component({
  selector: 'app-b',
  template: `
    <p>我是子组件 b</p>
    <app-c></app-c>
  `,
  styles: ['']
})
export class BComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }

}

现在页面上是这样的

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

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

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

@Component({
  selector: 'app-a',
  template: `
    <p>我是子组件 a</p>
    <app-c></app-c>
  `,
  styles: [':host ::ng-deep div { background-color: green !important; }']
})
export class AComponent implements OnInit {

  constructor() { }

  ngOnInit(): void {
  }

}

 页面如下

成功了

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

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

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

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

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

智能网联汽车的安全员高级考试涉及多个方面的专业知识,包括但不限于自动驾驶技术原理、车辆传感器融合、网络安全防护以及法律法规等内容。以下是针对该主题的一些核心知识解析: ### 关于智能网联车安全员高级考试的核心内容 #### 1. 自动驾驶分级标准 国际自动机工程师学会(SAE International)定义了六个级别的自动驾驶等级,从L0到L5[^1]。其中,L3及以上级别需要安全员具备更高的应急处理能力。 #### 2. 车辆感知系统的组成与功能 智能网联车通常配备多种传感器,如激光雷达、毫米波雷达、摄像头和超声波传感器等。这些设备协同工作以实现环境感知、障碍物检测等功能[^2]。 #### 3. 数据通信与网络安全 智能网联车依赖V2X(Vehicle-to-Everything)技术进行数据交换,在此过程中需防范潜在的网络攻击风险,例如中间人攻击或恶意软件入侵[^3]。 #### 4. 法律法规要求 不同国家和地区对于无人驾驶测试及运营有着严格的规定,考生应熟悉当地交通法典中有关自动化驾驶部分的具体条款[^4]。 ```python # 示例代码:模拟简单决策逻辑 def decide_action(sensor_data): if sensor_data['obstacle'] and not sensor_data['emergency']: return 'slow_down' elif sensor_data['pedestrian_crossing']: return 'stop_and_yield' else: return 'continue_driving' example_input = {'obstacle': True, 'emergency': False, 'pedestrian_crossing': False} action = decide_action(example_input) print(f"Action to take: {action}") ``` 需要注意的是,“同学”作为特定平台上的学习资源名称,并不提供官方认证的标准答案集;建议通过正规渠道获取教材并参加培训课程来准备此类资格认证考试
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值