首页>>前端>>Vue->Vue.js 组件deep选择器的用法和原理详解

Vue.js 组件deep选择器的用法和原理详解

时间:2023-11-29 本站 点击:1

随着代码规模的增长,前端项目中的 CSS 管理成了问题,其中之一就是 CSS 规则冲突。多人协作开发的项目,通过命名约定的方式有时候可能也无法完全避免。对此,不同的前端框架有不同的解决方案。Vue.js 提供了一种样式作用域(Scoped)的机制来防止组件之间的样式规则冲突。

一、scoped作用域

scoped原理:加上scoped属性后,在浏览器查看开发工具你会发现,组件模板里的每个 DOM 元素多了一个属性data-v-xxx,CSS 规则也有对应的属性选择器。这些属性名就是组件的唯一 ID,每个组件都不一样。配合 CSS 属性选择器,样式规则就只应用到对应的组件了,这样就能防止互相干扰了。

示例说明:

<stylescoped>.massif-table{.top-date{background:red;}}</style>

「原理:」当我们打开控制台,抓取到对应的dom元素后,在右侧会发现我们的「样式选择器」变成了

.massif-table.top-date[data-v-127071c6]{background:red;}

「选择器」最后的层级加了一串唯一的hash码「data-v-127071c6」以此来完成限制此样式只对改组件生效。

那么这也就是为什么在scoped的组件内无法修改同样有着scoped的子组件的样式,因为子组件和父组件的「hash码不一致」,选择器匹配不到,所以样式无法生效。

思考问题:组件只会给自己模板里的元素加上属性 data-v-xxx,而不会给子组件里的元素加这个属性。同时,生成的 CSS 属性选择器也是只到自己的 DOM 元素,无法应用到子组件内部的元素。

二、deep提升作用域

deep的原理就是将属性选择器里的属性移到上层,这样就能作用到所有子元素。

deep的主要作用是「css样式选择器作用域」的提升。deep肯定是和「scoped」属性结合使用的,那么首先我们就需要先了解一下scoped的作用

此时我们就需要使用 「deep」 来帮我们「提升作用域」

示例说明:

<stylescoped>.massif-table{.top-date{/deep/.sub-componpent{background:red;}}}</style>

现在我们再来看看渲染后的的样式:

.massif-table.top-date[data-v-127071c6].sub-componpent{background:red;}

不难发现 「data-v-127071c6」 这一串hash码被提到了 deep直接修饰的**「上一层级」**

三、错误的嵌套deep写法

其实与其说错误写法,倒不如说deep就不该有嵌套这种写法。

在我们对deep理解不深,并且有多层父子组件嵌套的时候,想在父组件修改子组件样式就可能会出现。

.fu{/deep/.zi1{/deep/.zi2{/deep/.zi3{background:red;}}}}

这种奇葩的写法。首先我们看看这种写法会被解析成什么鬼样子。

.fu[data-v-127071c6].zi1/deep/.zi2/deep/.zi3{bakcground:red;}

问题就来了,这种本身是不正确的,但是「浏览器却可以兼容」,完全无误的识别,所以样式会正常生效。但是手机浏览器就不会了。

四、(>>>) VS deep

<stylescoped>div>>>button{background-color:lightblue;}</style>

这里的三个大于号 >>>就是所谓的deep选择器。这里选择器的作用是,对div底下的所有button应用样式规则,即使是子组件内部渲染的button。

这里用了deep选择器另外一种写法,>>>跟/deep/的作用是一样的。之所以还有这种写法,是因为有些预编译器,比如 SASS,无法识别 >>>这种语法,会导致编译失败。这种情况下改用/deep/就好了。

总结

deep选择器不会经常用,但是能在特定的情况下解决特定问题。另外值得一提的是,deep选择器会应用到所有子组件里的元素,包括嵌套子元素。因此需要自己考虑影响范围,采取适当措施。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/Vue/812.html