样式修改失败】前几天开发需求,遇到一个坑,我无论怎么修改样式都无法完成 对公司内部的一个基础组件样式进行修改。经过排查,因为我在style标签上加入了scoped属性,于是我需要对scoped这个属性进行研究。

scoped作用

让.vue中的样式不影响其他.vue组件中的样式。

在vue组件中,为了使样式私有化(模块化),不对全局造成污染,在style标签上添加scoped属性,以表示它只属于当下的模块。

vue scoped踩坑记录_权重

如图所示,我添加了scoped属性,dom和 css选择器后面都会添加一个不重复的data属性,如图中的:data-v-f29e1056。

所以,scoped属性会做以下两件事:

  • 给HTML的DOM节点增加一个不重复的data属性。
  • 在每句css选择器的末尾(编译后生成的css语句)加一个当前组件的data属性选择器,对样式进行私有化。

于是我们会遇到两种情况:

  • 在不使用scoped的组件中加入了使用了scoped的组件。
  • 在使用了scoped属性的组件中加入了使用了scoped的组件。

在 不使用 scoped的组件中引用带scoped属性的组件

<template>
<div class="son-warp">
<son class="son">text</son>
</div>
</template>
...
<style scoped>
.son-warp{
display:inline-block;
}
.son{
padding: 5px 10px;
font-size: 12px;
border-raduis: 2px;
}
</style>


//father.vue
<template>
<div class="father">
<p class="title"></p>

<son></son>
</div>
</template>
...
<style>
.father{
width: 200px;
margin: 0 auto;
}
.father .son{
border-raduis: 5px;
}
</style>


最后的结果会是:

<div class="father">
<p class="title"></p>
<!-- son上面定义的组件 -->
<div data-v-f29e1056 class="son-warp">
<son data-v-f29e1056 class="son">text</son>
</div>
</div>
/*son.vue渲染出来的css*/
.son-warp[data-v-f29e1056]{
display:inline-block;
}
.son[data-v-f29e1056]{
padding: 5px 10px;
font-size: 12px;
border-radus: 2px;
}
/*father.vue渲染出来的css*/
.father{
width: 200px;
margin: 0 auto;
}
.father.son{
border-raduis: 5px;
}


此时由于权重关系,我们只需要调整对应的权重就可以调出我们需要的样式。

在 使用 scoped的组件中引用带scoped属性的组件

在父组件的style标签加入scoped属性

//father.vue
<template>
<div class="father">
<p class="title"></p>

<son></son>
</div>
</template>
...
<style scoped>
.father{
width: 200px;
margin: 0 auto;
}
.father .son{
border-raduis: 5px;
}
</style>


浏览器渲染的结果是:

<div data-v-57bc25a0 class="father">
<p data-v-57bc25a0 class="title"></p>
<!-- son是上面定义的组件 -->
<div data-v-57bc25a0 data-v-f29e1056 class="son-warp">
<son data-v-f29e1056 class="son">text</son>
</div>
</div>
/*son.vue渲染出来的css*/
.son-warp[data-v-f29e1056]{
display:inline-block;
}
.son[data-v-f29e1056]{
padding: 5px 10px;
font-size: 12px;
border-radus: 2px;
}
/*father.vue渲染出来的css*/
.father[data-v-57bc25a0]{
width: 200px;
margin: 0 auto;
}
.father .son[data-v-57bc25a0]{
border-raduis: 5px;
}


于是我们可以发现一个问题就是.father .son末尾的标记是father的标记,找不到对应的dom节点,于是我们设置样式就失效了。

vue scoped踩坑记录_css选择器_02

解决方法

  1. 引入样式
  2. 再写一个不加scoped的style(最好同时用BEM css命名规范 等方式去限定style影响范围)