在web开发中,css是一个利器,它可以使得我们的页面更加炫酷华丽,但是在好用的前提下它也给迭代开发带来了一定的麻烦,比如样式相互覆盖或者样式影响到了未考虑的元素等,所以css的私有化就显得很有必要了。
但从严格意义上来说,css样式都是全局的,并不存在私有作用域这一说法,所以我们会通过各种各样的方式来模拟实现css的私有化。其中大部分都说基于BEM思想来实现的。
css私有化的实现原则是匹配规则尽可能精确。比如通过全局唯一的id来匹配或通过全局唯一的class来匹配,如每一个需要赋予样式的元素都添加一个独一无二的类名,然后只通过类名来书写样式,避免使用通配符、标签选择器和后代选择器等。
在css私有化领域中非常出名的是BEM(Block Element Modifier)命名规则,它的主要思想是:
只通过 块__元素--修饰符 来定义规则
BEM的好处:清晰易懂,看到类名就知道作用是什么,方便维护;
BEM的缺点:丑、长(服务器开启gzip后会小一点);
简单介绍BEM后,我们再看看vue下的实现。在vue单文件组件下,我们只需要在style标签上添加scoped属性就可以实现css私有化的功能,那么它又是如何实现的呢?
![13908708-b11b077bedc85133.png](https://i-blog.csdnimg.cn/blog_migrate/01c5f7d61409acdb509ce5b994e6ee47.webp?x-image-process=image/format,png)
![13908708-1928f81857659084.png](https://i-blog.csdnimg.cn/blog_migrate/7d59f28b2491f6fe54cac461d87c10e1.webp?x-image-process=image/format,png)
可以清楚看到,添加scoped后,vue-loader加载器会做两个处理:
1、给html标签添加data-v-hash属性
2、给css样式添加[data-v-hash]选择器
这样一来,css样式就只对带有相应data-v-hash的标签起作用了,也就变现实现了css作用域的功能。
当然,在开发过程中,也会遇到父之间无法操作子组件样式的问题(比如在自己的页面上用了element-ui的el-button组件)
![13908708-b4a3c143a9c57ca1.png](https://i-blog.csdnimg.cn/blog_migrate/eb8ba533243fac2c74f79e18e51385cc.webp?x-image-process=image/format,png)
如果父组件加了scoped属性,那么所以规则都会自动在最后追加data-v-hash选择器,自然找不到子组件的元素,此时我们需要把父组件的scoped去掉,或者使用深度作用选择器
<style scoped>
.a >>> .b { /* ... */ }
</style>
参考链接:https://vue-loader-v14.vuejs.org/zh-cn/features/scoped-css.html