vue中scoped详解以及样式穿透>>>、/deep/、::v-deep

1、scoped

  • scoped属性用于限制样式仅应用于当前组件。
  • 当一个style标签拥有scoped属性时,它的CSS样式就只能作用于当前的组件,通过该属性,可以使得组件之间的样式不互相污染。

原理:当样式中加了scoped属性时候,编译的时候会自动给每一个dom节点都添加一个不重复的自定义属性,例如:data-v-4cd6f8b2(在同一个组件中,添加在所有节点上这个属性是一样的)

style标签拥有scoped属性编译后

通过代码可以看到加了scoped之后btnbg后面多了一个属性[data-v-4cd6f8b2]

2、样式穿透

  • 下面三种样式穿透的方法均不是标准css的一部分,而是vue的特殊语法
  • >>>、/deep/与::v-deep在实现效果上来说是一样的。它们都是Vue中用于穿透组件scoped样式隔离的语法,允许组件内的样式影响到子组件或更深层次的DOM元素

(1)>>>(适用于css原生样式)

如果项目使用的是css原生样式而没有用 scss 、sass、less ,那么可以直接使用 >>> 穿透修改

(2)/deep/ 与 ::v-deep 

项目中如果用到了预处理器 scss 、sass、less 操作符 ,那么用>>> 可能会因为无法编译而报错 ,比如在 <style lang="scss" scoped>,可以使用 /deep/或者::v-deep穿透

  • 在Vue 2.x项目中,/deep/和>>>被广泛使用来实现样式的穿透。
  • 在Vue 3.x项目中,推荐使用::v-deep来实现样式的穿透,因为它提供了更好的语义清晰度和兼容性

3、代码演示样式穿透

(1)暂且叫下面的组件为a组件,a组件中有一个testView组件

<template>
    <div class="test_bg">
        <testView></testView>
    </div>
</template>

<style lang="scss" scoped>

.test_bg{
    padding: 50px;
    background-color: #FAB32D;
    .test_app{
        background-color: rebeccapurple;
        width: 100%;
        height: 200px;
       .test_app_c{
            background-color: red;
            width: 100%;
            height: 100px;
            .test_app_c_a{
                background-color: green;
                width: 100%;
                height: 20px;
            }
        }
    }
}
</style>

(2)下面是testView组件,下面我们叫做b组件吧

<template>
    <div class="test_app">
        <div class="test_app_c">
            <div class="test_app_c_a"></div>
        </div>
    </div>
</template>

<script setup>
</script>

<style lang="scss" scoped>
.test_app {
    background-color: rebeccapurple;
    width: 50%;
    height: 200px;
   .test_app_c {
        background-color: red;
        width: 50%;
        height: 100px;
        .test_app_c_a {
            background-color: green;
            width: 50%;
            height: 20px;
        }
    }
}
</style>

上面代码style中用了scoped属性,父子组件相互隔离,样式彼此不受影响,运行代码如下图

其中外面黄色部分是a组件中的标签,紫色是b中的标签,按理说两个组件相互隔离,那么紫色部分应该渲染的是b组件里的样式,withd:50%,但是我们发现他其实是渲染a组件中的width:100%,后面子元素的样式才是渲染的b组件的样式,这里要注意,查看编译后的样式就能明白,a组件中添加了data-v-4cd6f8b2属性,b组件中隔离后往元素添加了data-v-5dd7fed2属性,test_app这个div同时添加了a和b组件的属性,样式被a组件的样式覆盖了

重点来了,这个时候如果我们想要样式穿透,在a组件中修改b组件中子元素的样式,那我们可以用/deep/ 或者 ::v-deep 来去掉每个元素中添加的属性,修改a组件中的样式代码后如下

.test_bg{
    padding: 50px;
    background-color: #FAB32D;
    ::v-deep .test_app{
        background-color: rebeccapurple;
        width: 100%;
        height: 200px;
        .test_app_c{
            background-color: red;
            width: 100%;
            height: 100px;
             .test_app_c_a{
                background-color: green;
                width: 100%;
                height: 20px;
            }
        }
    }
}

我们只是在.test_app前面加上了::v-deep,这个时候test_app后面所有的子元素就穿透了scoped的约束,实际上加上了::v-deep就是去掉约束data-v-4cd6f8b2以及data-v-5dd7fed2

下面对比看一下没加::v-deep与加上的区别

没加

加上后

从图可以看出,添加了::v-deep后test_app_c_a后面就去掉了[data-v-5dd7fed2],代码运行结果如下

大家可以通过代码以及运行效果图来对比,然后完全掌握约束的原理以及样式穿透的原理。

  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晨枫阳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值