文章目录

  • 1,前言
  • 2,scoped原理
  • 3,父子组件使用scoped的不同情况
  • 4,第一种:父组件未添加scoped,子组件未添加scoped
  • 5,第二种:父组件未添加scoped,子组件添加scoped
  • 6,第三种:父组件添加scoped,子组件未添加scoped
  • 7,第四种:父组件添加scoped,子组件也添加scoped
  • 8,解决方案
  • 9,总结

1,前言

我们知道vue为了防止css样式污染,在每个组件中提供了 scoped属性进行限定css作用域;
<style> 标签有 scoped 属性时,它的 CSS 只作用于当前组件中的元素。

2,scoped原理

1, vue中的 scoped 属性,其实就是给每一个dom节点元素都添加了不重复的自定义属性(如:data-v-6810cbe5);
2,然后编译时再给样式的末尾添加属性选择器进行样式私有化(如.btn[data-v-6810cbe5]);
如下:

转译前的代码:

btn组件(使用了Vant组件库的button组件):

<template><div class="copy1"><van-button type="default">默认按钮</van-button></div>
</template><style scoped lang="scss">
.van-button {background-color: red;}
</style>

浏览器编辑的结果如下:


可以看到,van-button类名后面添加了[data-v-03f66e5f];他的节点上面也自动添加了自定义属性 data-v-03f66e5f
所以:就算在两个互不相关的组件使用同样的类名,他们的样式也是互不影响的;

3,父子组件使用scoped的不同情况

scoped的这一操作,虽然达到了组件样式模块化的目的,但是会出现无论父组件样式的权重有多大,也可能无法修改子组件的样式;

下面就分四种情况具体说明scoped的作用:

4,第一种:父组件未添加scoped,子组件未添加scoped

这是最原始的一种情况,可以看到按钮的背景颜色为蓝色。此时父组件声明了background-color: blue;,子组件声明了background-color: red,权重是一样的,但是父组件style会覆盖子组件的style;
查看Elements后会发现,父组件的样式文件插入位置在子组件样式文件后面(上图可以看出一个是第9行一个是第90行),对于权重相同的样式,后面的会覆盖前面,所以父组件的style生效。

5,第二种:父组件未添加scoped,子组件添加scoped

子组件:btn.vue

<template><div class="copy1"><van-button type="default">默认按钮</van-button></div>
</template><style lang="scss" scoped>
.van-button {background-color: red;}
</style>

我们可以看到子组件的.van-button{background-color: red};被编译成.van-button[data-v-03f66e5f]{background-color: red}
子组件中button样式的权重=类选择器(.button)+属性选择器([data-v-03f66e5f]),而父组件中button样式的权重=类选择器(.button),所以子组件样式的权重加重了,覆盖本来能产生作用的父组件样式,导致按钮背景颜色为红色。

6,第三种:父组件添加scoped,子组件未添加scoped

父组件:

<template><div><!-- 使用子组件 --><div class="scoped1"><btn></btn></div></div>
</template><script>
//引入
import Btn from './copy1/index.vue';
export default {name: 'copy',components: {Btn,},
};
</script><style lang="scss" scoped>
.scoped1 {.van-button {background-color: blue;}
}
<style>

子组件:btn.vue

<template><div class="copy1"><van-button type="default">默认按钮</van-button></div>
</template><style lang="scss">
.van-button {background-color: red;}
</style>

我们可以看到按钮的背景颜色为红色,父组件style添加scoped后,所有元素都加上data-v属性,包括子组件的根节点,但是子组件的内层元素就不会受影响,所以父组件的.van-button[data-v-ae1b895c] {background-color:blue;}作用不到子组件的.van-button上。

这也是直接修改element-ui或vant-ui子组件的样式不生效的原因,就算要写,也需要借助深度作用选择器或样式不写在scoped属性中。

注意

如果只修改子组件根节点的样式,还是可以写到父组件的scoped CSS里面,因为一个子组件的根节点会同时存在 两个data-v属性的,一个是父组件本来的,另一个是子组件根节点上面的;(见上图左边部分);所以也会影响到子组件的根节点元素;

7,第四种:父组件添加scoped,子组件也添加scoped

效果图如下:


我们可以看到,子组件的根节点不仅有子组件的data-v属性,还有父组件的data-v属性。而.van-button元素依然不受父组件的影响,只拥有自己组件的data-v属性,所以按钮颜色依旧为红色。
这和上面第三种的情况是一样的;如法直接覆盖子组件的样式;

8,解决方案

那如果我就是想让父组件的样式覆盖子组件的样式,怎么办呢?

1,第一种使用两个style,一个用于私有样式(加scoped),一个用于共有样式。

<style lang="scss" scoped>
.van-button {....
}
// 公共样式
<style lang="scss" >
.van-button {background-color: blue;
}

2,深度作用选择器

父元素使用 /deep/ 或 >>>进行穿透

<style lang="scss" scoped>
/deep/ .scoped1 {.van-button {background-color: blue;}编译如下:[data-v-ae1b895c] .scoped1 .van-button {background-color: blue;}
}
<style>

有些像 Sass 之类的预处理器无法正确解析 >>>。这种情况下你可以使用 /deep/ 或 ::v-deep 操作符取而代之——两者都是 >>> 的别名,同样可以正常工作。

推荐使用 /deep/ 简单方便;

9,总结

1,scoped CSS里每个样式的权重加重了,理论上我们可以修改某一个样式,但是却需要更高的权重去覆盖这个样式;
2,无论父组件样式的权重多大,也可能无法修改子组件的样式,除了子组件的根节点。

END;

文章参考来自掘金喂。小欢:https://juejin.cn/post/6844903965746790408

vue - 深入理解vue中的scoped属性相关推荐

  1. vue中style scoped属性的作用和原理以及scoped穿透

    一.为什么要给style 节点加 scoped 属性(vue) 1.作用:当style标签里面有scoped属性时,它的css只作用于当前组建的元素.在单页面项目中可以使组件之间互不污染,实现模块化( ...

  2. 【Elasticsearch】Elasticsearch 理解mapping中的store属性

    1.概述 转载:https://www.cnblogs.com/sanduzxcvbnm/p/12157453.html 默认情况下,对字段值进行索引以使其可搜索,但不存储它们 (store). 这意 ...

  3. css布局margin介绍,深入理解css中的margin属性(推荐)

    之前我一直认为margin属性是一个非常简单的属性,但是最近做项目时遇到了一些问题,才发现margin属性还是有一些"坑"的,下面我会介绍margin的基本知识以及那些" ...

  4. Css3中align-content,深入理解css中的align-content属性

    align-content 作用: 会设置自由盒内部各个项目在垂直方向排列方式. 条件: 必须对父元素设置自由盒属性display:flex;,并且设置排列方式为横向排列flex-direction: ...

  5. 【Vue基础】关于Vue中CSS的scoped属性作用域与样式穿透

    scoped 在了解scoped属性之前,先了解一下Vue(中的插件)在渲染DOM时干了什么.Vue在渲染DOM后会在DOM节点上生成一个随机串data属性,这一属性给了当前组件下的DOM一种唯一标识 ...

  6. Vue中的scoped和scoped穿透

    1.什么是scoped 在Vue文件中的style标签上有一个特殊的属性,scoped.当一个style标签拥有scoped属性时候,它的css样式只能用于当前的Vue组件,可以使组件的样式不相互污染 ...

  7. vue 中的scoped原理

    scoped作用 在vue文件中的style标签上加上scoped属性,则style标签下的样式只能在本组件中使用. 如果每一个vue组件的style标签都加上了scoped,那就实现了样式的模块化. ...

  8. Vue中关于scoped以及scoped样式穿透的原理与使用详解

    1. scoped 当多个组件中有相同的元素或相同的类名时,在其中一个组件中更改该元素的样式,会导致所有组件中的样式更改,造成样式污染,若只想该样式在当前组件生效就需要用到scoped 示例 组件de ...

  9. Vue中的scoped的实现原理以及scoped穿透的用法

    本篇文章给大家带来的内容是关于Vue中的scoped的实现原理以及scoped穿透的用法(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 1.什么是scoped 在Vue文件 ...

最新文章

  1. 到底什么是MiddleWare(中间件),请用plain English描述
  2. 多线程:AQS的一些心得
  3. php图形界面框架,python GUI 图形化界面框架的选择
  4. 前端学习(3129):react-hello-react之回调形式的ref的次数问题
  5. [剑指offer][JAVA]面试题第[16]题[数值的整数次方][位运算][二分法]
  6. jeecg开源项目的IDEA的部署
  7. android 数据持久化——ContentProvider
  8. 学习U-Boot之--mkconfig
  9. Tcmalloc优化Mysql内存管理
  10. 3DMAX 的重要知识和插件介绍
  11. 【培训版】《最强大脑记忆力训练教程》[2017年7月份更新]
  12. 北理python复试_北理考研复试-北京理工大学考研复试经验
  13. 图的割点(解释及实现)
  14. 使用 Cobertura 和反射机制提高 Java 单元测试中的代码覆盖率
  15. 华为交换机测试吞吐量软件,华为选择Spirent验证最新数据中心交换机的性能
  16. 块级、内联、内联块级
  17. 详细解析java JDBC实现增删改查
  18. python--如何使用 Pylint 来检查分析Python 代码
  19. Swift协议与扩展
  20. 面试:逻辑题与思考题整理

热门文章

  1. not support mysql_MYSQL(解决方法):Client does not support authentication
  2. Java开发教程!java手册中文版
  3. 单片机c语言指针作用,单片机C语言教程:C51指针的使用
  4. 1400协议是什么和28181区别_28181平台对接接口详解
  5. Android程序员的春天!系统盘点Android开发者必须掌握的知识点,移动架构师成长路线
  6. 不是计算机专业可以报名系统集成项目管理工程师吗
  7. 【1170】计算2的N次方
  8. Android 输入法 控制 切换
  9. 中国年轻人与日本年轻人有什么不同
  10. CVPR2019论文题目中文列表