scoped的实现原理
当标签添加scoped属性,css只会作用于当前组件中的元素。vue中的scoped属性的效果主要是通过PostCss实现:
// 转译前
<style lang='less' scoped>
.example {
color: red;
}
</style>
<template>
<div class="example">scoped测试案例</div>
</template>
// 转译后
.example[data-v-aeba673c] {
color: red;
}
<template>
<div class="example" data-v-aeba673c>scoped测试案例</div>
</template>
转译后组件中的所有dom节点都添加上data属性,给css选择器额外添加一个对应的属性选择器,来选择组件中的dom,因此样式只能作用于含有该属性的dom元素(组件内部的dom)
修改第三方组件样式
最近在做一个项目使用到了Vant,借此做下记录。 项目的登录页面使用Vant的导航组件NavBar,默认的样式如下图所示:
但我希望的是效果是:
查看网页结构可以发现,决定导航栏背景色的类是 .van-nav-bar
在使用该导航栏的组件中:
.van-nav-bar {
background-color: #007bff;
}
使用scoped组件后,父组件的样式不会渗透到子组件,但是子组件的根节点是会受到父组件scope css的影响,.van-nav-bar类在子组件NavBar的根节点div上,因此在父组件中可以覆盖重写背景色。
如果需要继续修改导航栏的字体颜色,查看网页结构字体颜色由类 .van-nav-bar__title决定。
但.van-nav-bar__title所在并非是根节点,使用如下的写法是不会改变字体颜色。
.van-nav-bar {
background-color: #007bff;
}
.van-nav-bar__title {
color:#fff;
}
如果需要在局部组件中修改第三方组件库的样式,但又不想去除scoped属性造成组件之间的样式覆盖。此时可以通过特殊的方式穿透scoped
<style lang='less' scoped>
.van-nav-bar {
background-color: #007bff;
// less中使用 /deep/,Sass使用 >>>
/deep/ &__title {
color: white;
}
}
</style>
改变字体颜色成功: