当父子组件都使用了scoped的情况下,如何在父组件中控制子组件的样式?

450 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第24天,点击查看活动详情

1.发现问题

当父子组件都使用了scoped的情况下,如何在父组件中控制子组件的样式?

父组件要求标题为深蓝色

<template>
  <div class="dashboard-container">
    <son />
  </div>
</template>
<script>
import son from './son.vue'
export default {
  name: 'Dashboard',
  components: {
    son
  }
}
</script>
<style lang="scss" scoped>
 .title{
  color: darkblue;
}
</style>

子组件要求标题为粉红色

<template>
  <div>

    <h1 class="title">我是子组件</h1>
  </div>
</template>

<script>
export default {}
</script>

<style scoped lang="scss">
.title{
  color: pink;
}
</style>

  • 此时为粉红色,原因是子组件使用了scoped

scoped实现样式不被父组件样式修改的原理

  • scoped给标签加了自定义属性加强权重,并且使用交集选择器实现选中标签

2.解决问题

那么如何在父组件中控制子组件的样式?

这里我使用的是css预处理语言中的scss,

在选择器前加上::v-deep空格即可实现,我们看到标题变为了深蓝色

<template>
  <div class="dashboard-container">
    <son />
  </div>
</template>
<script>
import son from './son.vue'
export default {
  name: 'Dashboard',
  components: {
    son
  }
}
</script>
<style lang="scss" scoped>
::v-deep .title{
 color: darkblue;
}
</style>

实现原理

  • 在选择器前加上::v-deep空格,形成了父子选择器,覆盖了子组件的交集选择器
  • 实现穿透子组件的scoped,覆盖子组件的样式,

3.总结

样式穿透, 有三种写法:

  1. >>> 在less中使用

  2. /deep/ 在less中使用

  3. ::v-deep 在scss中使用

作用:

在父组件中能够修改子组件的样式

css权重覆盖

css选择器优先值:

  • 内联 > ID选择器 > 类选择器 > 标签选择器

CSS选择器都有权重值,权重值越大优先级越高。

  • 内联样式表的权重值最高,值为1000。
  • id选择器的权重值为100。
  • class选择器的权值为10。包括类选择器 , 属性选择器 和 伪类
  • 类型(元素)选择器的优先级为1。
  • 通配符选择器的优先级为0。

当权值相等时,后定义的样式表要优于先定义的样式表。

!important是顶级优先级