博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
vue组件样式scoped
阅读量:6577 次
发布时间:2019-06-24

本文共 3031 字,大约阅读时间需要 10 分钟。

1.vue组件中的样式如果没加scrped,样式代表的是全局样式(避免组件之间样式的冲突)。加了属性代表是模块化的。

        

其他组件引用button组件

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
//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分别就是:

1
2
3
4
5
6
7
<
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
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*button.vue渲染出来的css*/
.button-warp[data-v
-2311
c
06
a]{
  
display
:inline-
block
;
}
.button[data-v
-2311
c
06
a]{
  
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分别就是:

1
2
3
4
5
6
7
<
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
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*button.vue渲染出来的css*/
.button-warp[data-v
-2311
c
06
a]{
  
display
:inline-
block
;
}
.button[data-v
-2311
c
06
a]{
  
padding
:
5px
10px
;
  
font-size
:
12px
;
  
border-radus:
2px
;
}
/*content.vue渲染出来的css*/
.content[data-v
-57
bc
25
a
0
]{
  
width
:
1200px
;
  
margin
:
0
auto
;
}
.content .button[data-v
-57
bc
25
a
0
]{
  
border-raduis:
5px
;
}

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//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>

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

2.

总结一下scoped三条渲染规则

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

转载于:https://www.cnblogs.com/huancheng/p/9120417.html

你可能感兴趣的文章
(转载)bash: ./a.sh: /bin/bash^M: bad interpreter: No such file or directory的解决方法------dos--->unix...
查看>>
AngularJS开发指南13:AngularJS的过滤器详解
查看>>
利用boost将C++携程python可以调用的库
查看>>
正则表达式收藏
查看>>
python异常处理,日志处理
查看>>
COMMON INTERVIEW QUESTIONS
查看>>
HDU1164 Eddy's research I(解法二)
查看>>
UVA11192 Group Reverse
查看>>
UVA10603 Fill
查看>>
fwt模板
查看>>
立即执行函数: (function(){...})() 与 (function(){...}()) 有什么区别?
查看>>
sth else special(json distribution)
查看>>
如何让 height:100%; 起作用
查看>>
Java中list在循环中删除元素的坑
查看>>
[转]100个常用的linux命令
查看>>
cocos creator destroy方法
查看>>
第二课 HTML+CSS
查看>>
time random sys os模块
查看>>
第一章 台达组态软件的基本介绍
查看>>
DOM_04之常用对象及BOM
查看>>