本文讨论了Vue CLI中为Element UI添加样式为何不起作用的原因,以及正常思路的解决方案,废话比较多,随便看看就好了,如果关注问题的解决方案,请往后翻吧,等我弄明白简书如何做锚点跳转了再附上传送门。
前言
前端是个极好的行业,大家面对令人不怎么愉快的设计,在喷爽了之后,还是会认真想很多办法。这里推荐阅读黄玄的css-sucks-2015
关于如何书写CSS,使其能够适应大型项目,我们有很多办法,一开始有从命名上解决问题的:OOCSS、BEM ...... 一些CSS的扩展语言甚至为BEM的书写提供了便利,如SASS。
在组件化开发的思想获得大家的一致认可后,我们就如何书写“遗世而独立”的CSS进行了探索。
React说那就CSS in JS
吧,只需要养成一些极其别扭的习惯,我们就可以把所有的样式都用JS来表达,类似于以下写法:
...
render() {
const style = {
fontSize: '1.5em',
backgroudColor: 'red',
}
return (
<div style={style}>Something Amazing...</div>
)
}
...
当然,在定义keyframes、font-face、伪类、伪元素等时,可能会变得非常头疼(我现在还是没搞明白怎么用JS写这些玩意儿)。如果想要进一步了解,可以阅读阮一峰老师的CSS in JS 简介。
我们当然还有稍好一些的解决方案,依然不敌无需任何学习成本的CSS Module。
CSS Module
这种方案的学习成本实在是太低了,以致于我们在使用Vue CLI的时候没有意识到它的存在,这种方案的原理非常简单,就是我们在构建最终页面时为每个文件中的类名加上基于该文件路径的哈希值(我猜的),也就是所谓的scoped
解决方案(在vue单文件组件中的scoped属性与Firefox所支持的style标签的scoped属性是完全不一样的)。
<!--before build-->
<div class="title"></div>
<!--after build-->
<div class="title-hf3hb6sn"></div>
这样的写法会降低类名在浏览器中的可读性,对开发者不是很友好,尤其是对网络爬虫有了解的老师可能会知道,每次发版就更改类名实在是太丧心病狂了,这可能会让一些通过类名来定位信息的爬虫经常死掉。
Vue CLI中CSS Module的实现
在Vue CLI中我们通过为单文件组件中的style标签添加scoped
属性来启用CSS Module,与最初我们所设想的为类名添加哈希尾缀不同的是,Vue CLI利用了CSS的属性选择器,通过data-
属性来区别其他组件中使用相同类名的类。这样设计的目的在于使得当前的组件无法修改其他组件的样式。
<!--before build-->
<template>
<div class="demo">Hello, CSS Module</div>
</template>
<style scoped>
.demo {color: red;}
</style>
<!--after build-->
<template>
<div class="demo" data-v-20174629>Hello, CSS Module</div>
</template>
<style scoped>
.demo[data-v-20174629] {color: red;}
</style>
咋整呢?
明白了Vue CLI是如何工作的之后,我们也明白只需要不让Vue CLI为我们添加data-
属性就能解决这个问题,一般的思路是,在App.vue或者公用CSS文件中使用无scoped属性的style标签,并为其套上一层附有注释意义的父元素类名(也可以使用data-
进行注释),以免影响全局的样式:
<style>
.demo .el-option {
font-size: 1.5em;
}
</style>
这样的做法依然有问题,因为其占用了公共的命名空间。如何做到很好地封装第三方库,并写出“遗世而独立”的样式呢?哎,等我弄明白了再补充吧。