在vue组件中,为了使样式私有化(模块化),不对全局造成污染,可以在style标签上添加scoped属性以表示它的只属于当下的模块,这是一个非常好的举措,但是为什么要慎用呢?因为在我们需要修改公共组件(三方库或者项目定制的组件)的样式的时候,scoped往往会造成更多的困难,需要增加额外的复杂度。

scoped实现私有化样式的原理

为什么会说,会增加复杂度?那么我们先从的实现模块的原理说起。为了方便称呼,我们假设把这种组件叫做模块私有组件,其他的未加scoped的叫做模块一般组件。

通过查看DOM结构发现:vue通过在DOM结构以及css样式上加唯一不重复的标记,以保证唯一,达到样式私有化模块化的目的。具体的渲染结果是怎样的,通过一个例子来说明。

公共组件button组件

一个公共组件button,为了样式模块化,给其加上scoped属性,

//button.vue

<template>

<div class="button-warp">

<button class="button">text</button>

</div>

</template>

...

<style scoped>

.button-warp{

display:inline-block;

}

.button{

padding: 5px 10px;

font-size: 12px;

border-radus: 2px;

}

</style>

浏览器渲染button组件

button组件在浏览器渲染出的html部分和css部分分别为:

<div data-v-2311c06a class="button-warp">

<button data-v-2311c06a class="button">text</button>

</div>

.button-warp[data-v-2311c06a]{

display:inline-block;

}

.button[data-v-2311c06a]{

padding: 5px 10px;

font-size: 12px;

border-radus: 2px;

}

从上面的字可以看出,添加了scoped属性的组件,为了达到组件样式模块化,做了两个处理:

给HTML的DOM节点加一个不重复data属性(形如:data-v-2311c06a)来表示他的唯一性
在每句css选择器的末尾(编译后的生成的css语句)加一个当前组件的data属性选择器(如[data-v-2311c06a])来私有化样式
大家都知道css样式有一个优先级的说法,scoped的这一操作,虽然达到了组件样式模块化的目的,但是会造成一种后果:每个样式的权重加重了:理论上我们要去修改这个样式,需要更高的权重去覆盖这个样式。这是增加复杂度的其中一个维度。

其他组件引用button组件

上面分析了单个组件渲染后的结果,那么组件互相调用之后会出现什么样的结果呢?,具体分两种情况:模块一般组件引用模块私有组件(本质和模块私有组件引用模块一般组件一样);模块私有组件引用模块私有组件。

举个例子:在组件content.vue中使用了button组件,那么content.vue组件是否添加scoped属性渲染出来的结果有什么区别呢?

//content.vue

<template>

<div class="content">

<p class="title"></p>

<!-- v-button假设是上面定义的组件 -->

<v-button></v-button>

</div>

</template>

...

<style>

.content{

width: 1200px;

margin: 0 auto;

}

.content .button{

border-raduis: 5px;

}

</style>

模块一般组件(未添加scoped)引用模块私有组件

如果style上没有加scoped属性,那么渲染出来html和css分别就是:

<div class="content">

<p class="title"></p>

<!-- v-button假设是上面定义的组件 -->

<div data-v-2311c06a class="button-warp">

<button data-v-2311c06a class="button">text</button>

</div>

</div>

/*button.vue渲染出来的css*/

.button-warp[data-v-2311c06a]{

display:inline-block;

}

.button[data-v-2311c06a]{

padding: 5px 10px;

font-size: 12px;

border-radus: 2px;

}

/*content.vue渲染出来的css*/

.content{

width: 1200px;

margin: 0 auto;

}

.content .button{

border-raduis: 5px;

}

可以看出,虽然在content组件中,修改了button的border-raduis属性,但是由于权重关系,生效的依然是组件内部的样式(此时是外部的样式被覆盖)。所以如果要达到修改样式的目的,就必须加重我们要修改样式的权重(增加选择器层级,ID选择器,并列选择器,impotant等)

模块私有组件(添加scoped)引用模块私有组件

如果加了scoped属性呢?按照开始分析出来的规则(事实也是这么的):

首先是在所有的DOM节点加上data属性

然后在css选择器尾部加上data属性选择器

那么渲染出来html和css分别就是:

<div data-v-57bc25a0 class="content">

<p data-v-57bc25a0 class="title"></p>

<!-- v-button假设是上面定义的组件 -->

<div data-v-57bc25a0 data-v-2311c06a class="button-warp">

<button data-v-2311c06a class="button">text</button>

</div>

</div>

/*button.vue渲染出来的css*/

.button-warp[data-v-2311c06a]{

display:inline-block;

}

.button[data-v-2311c06a]{

padding: 5px 10px;

font-size: 12px;

border-radus: 2px;

}

/*content.vue渲染出来的css*/

.content[data-v-57bc25a0]{

width: 1200px;

margin: 0 auto;

}

.content .button[data-v-57bc25a0]{

border-raduis: 5px;

}

对于上面的两种情况,可以明显看出来渲染后的结果大不相同。

虽然我们在content添加了想要修改button组件的样式的代码,但是仔细看,由于.content .button这句在末尾加的是content组件的scoped标记,最后这句其实根本作用不到我们想要的DOM节点上,所以这种情况我们在content内部写的任何样式都不会影响到button.vue组件,所以这就尴尬了。。。。

当然这个问题也是可以解决的,就是直接加全局样式可以修改到,但这势必会影响全部地方的组件;所以需要另外一种方法在content.vue组件内再加一个不带scoped属性的style标签,也就意味着要加两个style,一个用于私有样式,一个用于共有样式。这肯定是有点shit的,并且这两种解决方案都回避不了一个问题:权重!!!

//content.vue

<template>

<div class="content">

<p class="title"></p>

<!-- v-button假设是上面定义的组件 -->

<v-button></v-button>

</div>

</template>

...

<style scoped>

.content{

width: 1200px;

margin: 0 auto;

}

</style>

<style>

.content .button{

border-raduis: 5px;

}

</style>

这样符合规范么?貌似没看到不能这么写,并且这么写也确实生效了。。。但这样确实增加了思维的复杂度,有点苦恼啊。

总结scoped的渲染规则

总结一下scoped三条渲染规则

给HTML的DOM节点加一个不重复data属性(形如:data-v-2311c06a)来表示他的唯一性
在每句css选择器的末尾(编译后的生成的css语句)加一个当前组件的data属性选择器(如[data-v-2311c06a])来私有化样式
如果组件内部包含有其他组件,只会给其他组件的最外层标签加上当前组件的data属性
解决方案

对于引用的三方库,如果对方使用了scoped,我们无力改变什么,如果确实需要修改他的样式最能在不加scoped的组件中修改样式,或者全局样式直接修改,这很粗暴!

对于自己维护的组件,一定要想清楚,组件的样式能否满足所有的情况。如果确实需要加,无疑会增加使用这个组件的开发同学的工作!
---------------------
原文:https://blog.csdn.net/margin_0px/article/details/83014024

转载于:https://www.cnblogs.com/Health-zhang/p/10862686.html

vue中style下scope的使用和坑相关推荐

  1. vue中style的scoped属性的设计方式

    vue中style的scoped属性这里是怎实现的呢? scoped三条渲染规则 给HTML的DOM节点加一个不重复data属性(形如:data-v-2311c06a)来表示他的唯一性 在每句css选 ...

  2. vue中style的scoped属性这样用,修改第三方组件iview 或 element 样式

    vue中style的scoped属性这样用,修改第三方组件iview 或 element 样式 文章目录 vue中style的scoped属性这样用,修改第三方组件iview 或 element 样式 ...

  3. 理解vue中的slot-scope=“scope“

    理解vue中的slot-scope="scope" slot是插槽,slot-scope="scope"相当于一行的数据 <el-table-column ...

  4. Vue中select下拉框的默认选中项的三种情况

    在Vue中 使用select下拉框 主要靠的是 v-model 来绑定选项 option 的 value 值. select下拉框在界面的展示,我们都希望看到框中有一个值 而不是空白,比如显示 &qu ...

  5. vue中style的scoped属性

    原文链接(这两篇讲得超级好):vue中慎用style的scoped属性_June.1的博客-CSDN博客_scoped scoped 和 deep的用法深究_格竹悟道的博客-CSDN博客_scoped ...

  6. vue中使用keepAlive组件缓存遇到的坑

    项目开发中在用户由分类页category进入detail需保存用户状态,查阅了Vue官网后,发现vue2.0提供了一个keep-alive组件. 上一篇讲了keep-alive的基本用法,现在说说遇到 ...

  7. 工作总结8:关于Vue中的slot-scope=“scope“

    <template><el-table :data="tableData" style="width: 100%">//---:data ...

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

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

  9. vue mui html不解析,记下Vue中使用Mui.js踩到的坑

    1. mui.js 推荐全局引用 Mui的css,js以及扩展js,推荐在main.js全局引用即可,千万不要再在子组件中重复引用,虽然不会报错 但是某些插件的返回结果会有意向不到的后果,比如numb ...

  10. 在Vue中使用vant的方法,踩坑in ./node_modules/vant/es/dialog/Dialog.js

    步骤一:使用npm安装vant npm install vant -force 因为可能会产生依赖冲突,所以一般会在后面加上 -f 强制执行 步骤二:导入vant包 在Vue项目的main.js文件中 ...

最新文章

  1. Winform中设置ZedGraph鼠标悬浮显示线上的点的坐标并自定义显示的内容
  2. vb跨域访问ajax,解决AJAX的跨域访问-两种有效示例
  3. 通过移位的方式实现相加算法
  4. :寻找指定和的整数对_寻找时间:如何增加设计的时间
  5. java 字符串文字筛选_重新开始Java的原始字符串文字讨论
  6. WebDriver API元素的定位
  7. git修改已提交记录的注释
  8. bz 1029: [JSOI2007]建筑抢修
  9. OCS 2007 R2搭建后端SQL 2005企业版池
  10. STM32串口编程易错点
  11. 前端面试宝典总结(一)(搬自牛客)
  12. 快速入门学习数字图像处理(冈萨雷斯第三版)
  13. vb.NET 关于进度条控件使用
  14. Oracle 数据库sql语句修改表字段的字段类型和长度
  15. No service of type FactoryLoggingManagerInternal available in ProjectScopeServices.
  16. android7 强制gpu渲染,安卓手机开启强制GPU渲染功能的方法
  17. Creo4.0手动添加第三方零件库
  18. SQL服务器日志自动收缩,SQLServer2008日志收缩
  19. 青岛智慧城市建设以人为本 勾勒未来图景
  20. python canvas画弧度_趣玩 Python 之绘制基本图形

热门文章

  1. WPF中自定义的DataTemplate中的控件,在Window_Loaded事件中加载机制初探
  2. Vue.js自定义指令的用法与实例
  3. Nginx如何实现读写限流的方法
  4. 项目管理:实现按时、按预算、基于目标的交付的七个步骤
  5. 全面启动远程医疗行业
  6. KTable的设置单元格属性
  7. nodemon运行 提示错误:无法加载文件 C:\Users\gxf\AppData\Roaming\npm\nodemon.ps1,因为在此系统上禁止运行脚本。...
  8. WPF Invoke与BeginInvoke的区别
  9. web移动端常见问题解决方案 (转)
  10. C++中容器的使用(二)