之前没有接触过::v-deep
、/deep/
、>>>
这些深度选择器,但是考虑到最近接触到的项目封装程度比较高,所以有时候在改动公共组件而不影响其他地方使用的时候,这些东西就能起到作用了。除了深度选择器,也还可以利用父传子传参数进行实现,当然,这很暴力qwq。
例如:
- 直接设置一个
custom-style
的属性,然后进行传递style
值:{width:"100px"}
- 假如用的是
windicss
这类原子化css
框架的话,也可以传递类名:w-[100px]
- 第三种方法就行利用深度选择器了。
使用
在使用深度选择器的时候,需要先设置一个parent
类,然后在进行针对子组件编写style
样式。
javascript
// parent.vue-template
<div class="parent">
<child></child>
</div>
// child.vue-template
<div class="child">child</div>
然后再在parent
组件里面编写style
样式
xml
<style lang='scss'>
.parent {
&::v-deep(.child) {
color: "red";
}
}
</style>
这个时候就基本上使用成功了。
原理
什么是scoped?
在了解它如何工作之前,得需要先了解一下vue
的scoped
是如何隔离命名冲突 的。在进行对vue
的style
添加完scoped
属性后,vue
在进行编译的期间,会将单文件组件的唯一哈希进行绑定到css
选择器上。例如:.child[data-v-xxx]
,打开f12
查看网页的html
也可以看见vue
组件的盒子会多一个属性。如图所示:
当有了这个玩意后,vue
在编译style
的时候,进行判断是否添加了scoped
,如果有,就将此哈希进行添加到所有选择器上去,从而实现样式隔离。
加了 scoped
没加 scoped
详细原理可以看这篇文章:知乎-vue的scoped原理
深度选择器是如何工作的?
当了解完scoped
后,deep
就很简单了,原理跟scoped
差不多,也是利用scopedId
进行,但是不通的是:
scoped
是给自己的style
加并且是给最后一个选择器进行加。deep
是给父级加,子不加。
看代码和图就懂了
xml
<template>
<div class="text">
text
<p class="p">p标签</p>
</div>
</template>
<style scoped>
.text .p {
color: red;
}
</style>
xml
<script setup name="parent">
import child from './components/child.vue'
</script>
<template>
<div class="flex flex-col h-screen w-screen parent justify-center items-center">
<child msg="Vite + Vue" />
</div>
</template>
<style scoped lang="scss">
.parent {
&::v-deep(.text) .p{
color: #f0f;
}
}
</style>
看见两个的差别了没,一个是.text .p[data-v-xxx]
另外一个是.text[data-v-xxx] .text .p
,前者的权重为[0,3,0]
,后者权重为[0,4,0]
。也就是这里值得特定性。所以浏览器会使用深度选择器所指定的样式。但是如果子组件内部用了!important
,那这个特定性 就是[1,0,2,0]
了,比deep
所指定的要大了。就改不动了。除非你deep
的地方也加!important
最后
大致分享就这些了,这只是我个人学习的记录,希望对你们有帮助,如有说的不对,也希望大佬评价进行指错。