Vue中的scope详解以及使用/deep/解决组件样式不起作用

一.scope

在vue中,我们为了避免父组件的样式影响到子组件的样式,会在style中加<style scoped>,这样父组件中如果有跟子组件相同的class名称或者使用选择器的时候,就不会影响到子组件的样式。

具体来说,使用 scoped 属性后,你在样式中定义的选择器会被自动转换为带有特定哈希前缀的选择器,以确保它们只影响当前组件的元素。这种方式可以有效地避免全局样式冲突问题,使得组件的样式更加独立和可预测。

①我们在组件加了 scoped 之后,组件的根元素的样式会自动添加一个hash值。

 例子:比如我现在新建了一个名字为homeIndex的vue组件,该组件的根元素为类名为home-container的div 

<template>
  <div class="home-container">
    <van-button>哈哈哈</van-button>
  </div>
</template>
 
<script>
export default {
  name: 'homeIndex',
 
  data() {
    return {
      active: 2
    };
  },
 
  mounted() {
 
  },
 
  methods: {
 
  }
}
</script>
 
<style lang="less" scoped>
</style>

打开控制台:可以看到组件的根元素的style样式中就添加了哈希值

在这个示例中,使用了 scoped 属性,所以 .home-container样式会被转换为类似 .home-container[data-v-f3f3eg9] 的选择器,其中 data-v-f3f3eg9 是一个哈希值,用于确保样式只作用于当前组件。

需要注意的是,scoped 属性只对当前组件的直接子元素起作用。如果你希望样式作用于子组件内部的元素,你需要在子组件中也使用 scoped 属性。

 

②在父组件中,最多只能影响子组件的根元素,意思就是在父组件的样式中只能修改子组件根元素的样式 

 例子:现在我们在home-container组件引入了van-tabs组件,并起类名为channal-tabs,那么现在home-container为父组件,van-tabs组件为子组件,而现在我们又通过在父组件修改子组件的根元素的样式  .channal-tabs { color: red;},那么这样是可以在父组件中修改子组件的样式的。

<template>
  <div class="home-container">
    <!-- 频道栏 -->
    <van-tabs v-model="active" animated swipeable class="channal-tabs">
      <van-tab title="标签 1">内容 1</van-tab>
      <van-tab title="标签 2">内容 2</van-tab>
      <van-tab title="标签 3">内容 3</van-tab>
      <van-tab title="标签 4">内容 4</van-tab>
      <van-tab title="标签 4">内容 4</van-tab>
      <van-tab title="标签 4">内容 4</van-tab>
      <van-tab title="标签 4">内容 4</van-tab>
      <van-tab title="标签 4">内容 4</van-tab>
      <van-tab title="标签 4">内容 4</van-tab>
    </van-tabs>
    <!-- 频道栏 -->
  </div>
</template>
 
<script>
export default {
  name: 'homeIndex',
 
  data() {
    return {
      active: 2
    };
  },
 
  mounted() {
 
  },
 
  methods: {
 
  }
}
</script>
 
<style lang="less" scoped>
.home-container {
 
  .channal-tabs {
    color: red;
  }
}
</style>

打开控制台:可以看到父组件的样式中只能修改子组件根元素的样式

 ③注意!注意!注意!在父组件中,最多只能影响子组件的根元素,而不能修改子组件根元素更里层的样式 

例子:比如我们在父组件home-container修改子组件channal-tabs更深层的元素van-tab__pane的样式.van-tab__pane {  color: red;}这样是无法修改的

<template>
  <div class="home-container">
    <!-- 频道栏 -->
    <van-tabs v-model="active" animated swipeable class="channal-tabs">
      <van-tab title="标签 1">内容 1</van-tab>
      <van-tab title="标签 2">内容 2</van-tab>
      <van-tab title="标签 3">内容 3</van-tab>
      <van-tab title="标签 4">内容 4</van-tab>
      <van-tab title="标签 4">内容 4</van-tab>
      <van-tab title="标签 4">内容 4</van-tab>
      <van-tab title="标签 4">内容 4</van-tab>
      <van-tab title="标签 4">内容 4</van-tab>
      <van-tab title="标签 4">内容 4</van-tab>
    </van-tabs>
    <!-- 频道栏 -->
  </div>
</template>
 
<script>
export default {
  name: 'homeIndex',
 
  data() {
    return {
      active: 2
    };
  },
 
  mounted() {
 
  },
 
  methods: {
 
  }
}
</script>
 
<style lang="less" scoped>
.home-container {
  .channal-tabs {
    .van-tab__pane {
      color: red;
    }
  }
}
</style>

打开控制台:可以看到样式并没生效

 如果我们需要在父组件中修改子组件的样式怎么办? 

这时候就需要使用/deep/,修改子组件的样式代码

<style lang="less" scoped>
.home-container {
  /deep/.channal-tabs {
    .van-tab__pane {
      color: red;
    }
  }
}
</style>

打开控制台:

可以看到成功在父组件中修改子组件更深层的样式 

二、>>>、/deep/以及::v-deep(意思是更深层的意思) 

 以上三种的效果均是在父组件改变子组件更深层元素的样式。  

  一些预处理器(例如Sass)可能无法正确解析>>>。在这些情况下,可以改用/deep/::v-deep组合器,两者都是它的别名,并且和>>>工作原理完全相同。

三.总结

 1.给组件加scope后,该组件的根元素的样式会自动添加哈希值,表示该组件的样式不会影响其他组件(一般第三方组件,比如vant组件都会有哈希值)
2.默认只能在父组件修改子组件根元素的样式,如果想修改子组件更深层元素的组件的样式,就给子组件样式加/deep/(浏览器兼容性最好)

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Vue 使用 `/deep/` 或 `::v-deep` 可以解除样式作用域限制,允许您在子组件修改父组件样式。但是需要注意的是,`/deep/` 在 Vue 2.x 已被废弃,取而代之的是 `>>>` 或 `::v-deep`。 如果您在使用 `/deep/` 或 `::v-deep` 时报错,可能是因为您的 CSS 预处理器(如 SCSS)不支持这些选择器。这是因为 `/deep/` 或 `::v-deep` 是 Vue 特定的选择器,不是标准的 CSS 选择器。 解决方法是使用其他方法来实现样式穿透,或者尝试更新您的 CSS 预处理器版本以获得对 `/deep/` 或 `::v-deep` 的支持。例如,您可以使用以下方法来实现样式穿透: 1. 使用 `>>>` 或 `::v-deep` 代替 `/deep/`。在 Vue 2.x ,可以将 `/deep/` 替换为 `>>>` 或 `::v-deep` 来实现相同的效果。 例如,如果您想穿透到子组件修改标题的样式,可以这样写: ```scss <style lang="scss" scoped> .parent { /deep/ .child { /* 修改子组件样式 */ } } </style> ``` 可以替换为: ```scss <style lang="scss" scoped> .parent { >>> .child { /* 修改子组件样式 */ } } </style> ``` 2. 使用 `::v-deep` 代替 `/deep/`。在 Vue 2.x ,您还可以使用 `::v-deep` 来实现样式穿透。 例如,如果您想穿透到子组件修改标题的样式,可以这样写: ```scss <style lang="scss" scoped> .parent { /deep/ .child { /* 修改子组件样式 */ } } </style> ``` 可以替换为: ```scss <style lang="scss" scoped> .parent ::v-deep .child { /* 修改子组件样式 */ } </style> ``` 请注意,以上方法需要您的 CSS 预处理器支持 `>>>` 或 `::v-deep` 选择器。如果您仍然遇到问题,请检查您的 CSS 预处理器文档或更新预处理器版本以获得支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值