即将弃用 ::ng-deep - 有替代方法吗?

57

文档显示:

穿透影子后代选择器已经过时,在主流浏览器和工具中不再支持。因此,我们计划在 Angular 中停止支持所有 /deep/、>>> 和 ::ng-deep 3 种方式。在此之前,应优先使用 ::ng-deep 以获得更广泛的工具兼容性。

既然我想升级到新版本而不改变代码,那么被弃用方法的替代方法是什么?


3
如果您尝试在模板中样式化子组件中的DOM节点,则由于其样式封装(模仿浏览器中的shadow DOM),Angular的样式不会像@trichetriche所说的那样,简单地向HTML元素添加类或其他选择器。 - Daniel W Strimpel
@DanielWStrimpel,这就是为什么我要求提供一个 [mcve]。只需删除封装或使用全局样式,仅使用组件选择器即可摆脱该伪选择器。 - user4676340
1
@trichetriche 只需使用组件选择器,您就可以摆脱伪选择器。是的,只要您删除封装即可。 - Daniel W Strimpel
1
我在用手机,所以我看不到plunkr,但我已经这么做了两年多了,所以我真的不知道你在说什么。封装会向您的元素添加随机属性,我不明白样式表怎么会破坏这个。 - user4676340
这个回答解决了您的问题吗?在::ng-deep的位置上使用什么 - kapsiR
显示剩余7条评论
2个回答

56
在研究了委员会会议实际记录后,似乎还没有提出替代方案。使用::ng-deep语法可以确保让Angular负责打破样式封装(对于模板中子组件的DOM节点),从而使用你的样式(而不是使用浏览器原生特性,使其更具未来性)。我认为这个注释只是想让你知道,每当实际的浏览器机制被放置时,他们计划实施它。我个人不会回避使用它。
在CSS中不使用该运算符的唯一方法是完全放弃让Angular管理组件的样式封装,方法如下:
import { ViewEncapsulation } from '@angular/core';

@Component({
    ...
    encapsulation: ViewEncapsulation.None
})

如果你这样做,你的样式会变成全局的,所以请确保在每个样式规则前加上你的组件名称,以确保它们不会泄漏到其他地方。例如,如果你有一个选择器为my-custom-componentMyCustomComponent组件:
my-custom-component button { ... } /* good */
button { ... } /* bad */

请参考此答案 https://dev59.com/8VYN5IYBdhLWcg3wuKC5#49308475 和评论以获取更多细节和解决方案。 - Ferie
最好在规则前加上:host,而不是my-custom-component。此外,如果您的项目使用SCSS,您可以将所有规则放在一个:host规则中,如:host { /* 我的规则 */ } - undefined

2

一种可行的替代方案是将CSS样式包含在全局的styles.scss文件中*。

例如,假设您想要为在<mat-form-field>下生成的<div class="mat-form-field-flex">元素添加样式,您可以使用::ng-deep

your.component.scss

::ng-deep mat-form-field.mat-form-field div.mat-form-field-flex {
  padding: 0 0 0 .75em;
}

或者,您可以更改:

styles.scss:

mat-form-field.mat-form-field  div.mat-form-field-flex {
  padding: 0 0 0 .75em;
}

*:这是添加到您的angular.json文件中样式集合中的任何文件。

"styles": [
          "src/theme.scss",
          "src/styles.scss"
        ],

2
是的,这是有道理的,因为全局样式文件是用于包含所有 Angular 应用程序和组件的全局 index.html 文件的,尽管该索引没有任何等效于 ViewEncapsulation.None 的 Angular 预构建封装。但我认为这不是一个好方法,因为在全局文件中组织所有应用程序样式会很困难,除非您创建一个自定义样式文件夹,将所有 ng-deep 自定义样式放置在其中,然后将其导入到全局样式文件中。 - getName

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接