Vue css样式穿透和权重

普通的html、CSS结构,样式权重为 !important > 行内 > 头部 > 引入。但是在vue里面,我们的文件结构发生改变,不再是html文件而是vue文件,<style></style>将解析为组件也不是头部样式,这时样式权重比较复杂,下面我们来详细说一下。

vue样式作用域分为两种:

  • 全局:顾名思义即影响所有文件的样式 ,定义在App.vue中
  • 私有:仅作用于当前文件dom元素的样式;私有又分为两种情况,父组件和子组件

一般情况下是 子组件 > 父组件 > 全局,但是有时候我们会有些特别的需求。

例如现在有一个公共按钮组件,我们在几个页面中调用它。

<template>
    <div>
      <button>tab1</button>
    </div>
</template>

<script>
    export default {
        name: "slotVue3"
    }
</script>

<style scoped>
  button{
    background: #abcdef;
    border: none;
    padding: 10px 20px;
    border-radius: 3px;
    margin-top: 30px;
  }
</style>

在这里插入图片描述
但是在首页调用的时候,要求改变按钮颜色。我第一个想法就是在父组件里重写样式,覆盖颜色,但是由于权重关系,并没有起效。要想效果生效,需要给样式添加>>>深度作用选择器。

<style scoped>
  /* 无效
  button{
    background: yellowgreen !important;
  } */
  >>>button{
    background: yellowgreen !important;
  }
</style>

在这里插入图片描述

深度作用选择器是vue-loader的一个属性,作用于

  • 影响子组件
  • 动态生成的内容

通过 v-html 创建的 DOM 不受 scoped 样式影响,但是我们可以通过深度作用选择器来为他们设置样式。

<template>
<div v-html="dom"></div>
</template>

<script>
export default {
      data(){
        return{
          dom: "<h5 class='title5'>Test V-html</h5>",
        }
      }
    }
</script>

<style scoped>
/* 无效
title5{
    color: darksalmon;
}
*/

>>>.title5{
   color: darksalmon;
}
</style>

在这里插入图片描述
你需要重写哪个元素的样式,作用器就放在那个元素的前面!

还有一种情况就是作为插件引入的样式文件,如果我们想修改插件的默认样式,重写后在测试环境下没有问题,但是打包后发现不起效。是因为在main.js中引入的插件样式放在了app.vue中的前面。

有两个解决方案:

  • 配合>>>在样式后加!important;
  • 在main.js中将放到引入的插件后,这样子写app.vue中的样式权重就比插件的样式权重高了;
import 'swiper/css/swiper.min.css'
import 'bootstrap/dist/js/bootstrap.min'
import 'bootstrap/dist/css/bootstrap.min.css'
import 'animate.css';
import "vue-image-lightbox/dist/vue-image-lightbox.min.js"
import "vue-image-lightbox/dist/vue-image-lightbox.min.css"
import VueLazyload from "vue-lazyload";  //懒加载

import App from './App'

需要注意的是:

  • 对标签名使用深度作用器时,会影响性能,慢很多倍。使用class或者id则无性能影响。如 >>>p { color: red }>>>.example { color: red } 性能要慢。

  • 在递归组件中小心使用后代选择器! 对选择器 .a .b 中的 CSS 规则来说,如果匹配 .a 的元素包含一个递归子组件,则所有的子组件中的 .b 都将被这个规则匹配。

  • 如果是使用SASS或者LESS预处理器编写CSS,一样可以使用深度作用处理器,不过需要改为/deep/::v-deep


参考:深度作用选择器

Vue 2样式穿透(Scoping Inheritance)是一种设计模式,用于解决组件内部CSS规则对父级元素影响的问题,通常在采用单文件组件(SFC)和Vue CLI构建的应用。当一个组件需要修改其根元素的一些样式时,如果直接写在`.vue`文件的`<style>`标签内,样式会作用于整个应用,这可能会导致命名冲突。 然而,在Vue 2的默认配置下,如果你使用了内置的 scoped 样式(即前缀为 `.` 的选择器),它会限制样式的应用范围到当前组件及其所有后代。这意味着,除非你在组件外部显式地引入未scoped的样式,或者使用`:v-deep` 或 `>>>` 伪元素穿透样式,否则父组件无法直接访问子组件的 scoped 样式。 如果你发现样式穿透失效,可能是以下几种情况: 1. **未正确使用穿透符**:在父组件的样式,你需要使用 `::v-deep` 或 `>>>` 来穿透子组件的 scoped 样式。例如:`.parent ::v-deep .child-class { ... }`。 2. **全局注册的样式库**:某些全局使用的CSS库如Element UI、Vuetify等,它们有自己的CSS模块系统,可能导致样式覆盖。在这种情况下,你需要确认是否正确处理了库内的穿透规则。 3. **CSS预处理器(如Sass、Less)**:在预处理器,如果不小心,你可能需要手动转换或配置来支持穿透。 4. **CSS冲突**:两个组件同时设置了相同的样式,优先级较高的样式会生效。 5. **版本问题**:Vue 2.6及以上版本引入了更严格的CSS scoping,确保样式仅作用于组件自身。如果使用的是早期版本,可能需要升级或调整设置。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值