ui/├── layout/| ├── Header.js // component code| ├── Header.scss // component styles| ├── Header.spec.js // component-specific unit tests| └── Header.fixtures.json // any mock data the component tests might need├── utils/| ├── Button.md // usage documentation for the component| ├── Button.js // ...and so>使用一致的类名空间对于类名和其他标识符(如ID、动画名称等)而言,CSS只具有一个单一的、无区分性的命名空间。而对于这一问题的解决方法,人们采用了与过去的PHP时代一样的解决方法,即:使用长而具有结构性的命名方式(BEM 来完成对于命名空间的命名。我们将选用一种命名标准并贯彻执行。
举个例来说, 用 myapp-Header-link
作为一个类名. 而它的每一个部分都有明确的功能:
myapp
:用于区分使用在同一DOM树上的不同app
Header
:用于区分app中的不同组件
link
: 声明了组件空间中的一个局部名称,达到了我们想设置局部样式的目的
但有一个特例,就是Header
组建的根元素只需要使用myapp-Header
这个类名进行标识即可。并且对于一个简单的组件而言,这可能就是你所全部需要的命名。
不管是采用了哪一个命名规范,我们都需要坚持使用这一种方法。而这种命名方式中的三个部分除了有其特定的功能,还具有相应的含义。故而在看到一个类名的时候,你会看出它属于哪个部分。也就是说,命名空间可以帮助我们在浏览项目的样式文件时准确归类。
我将这种命名的模式设定为:app-Component-class
, 而且这也是我工作中行之有效的方法。当然,你也可以提出你自己的设置模式。
4. 让命名空间和文件名间具有映射关系
这一条规则是上面两条规则(将相关代码放在一起,类的命名空间)的组合,即:所有会影响到同一组件的样式规则应该放在以该组件命名的文件中。
如果你正在使用浏览器观看效果,并且定位到一个表现异常的组件,你可以依次点开这个组件,假设你会看到以下代码:
<div class="myapp-Header">...</div>
接着你可以切换到你的编辑器,在敲击了“快速打开文件”的组合键之后,利用你刚获取到的名称--head--进行搜索,然后看到:
而UI组件和其对应的编码文件间所具有的严格映射,对于新进入项目而又不熟悉项目架构的人来说无疑是有用的。
当然,还有一个推论(虽然现在可能不太明显):一个样式文件中应该只含有一个命名空间中的样式。为什么这么说呢? 举个例子吧。现在有一个登陆的表单,它只会用在Header
组件中. 而与其相关的js,我们定义在了一个名为Header.js
的文件中, 并且不会向其他地方“暴露”该文件。然后,给这个表单赋予了一个类名,即myapp-LoginForm
, 并将在Header.js
文件和Header.scss
使用它。现在,假设有一个新来的人要去修改这个登录表单在布局上的一些小问题 并且他要去判断从哪个元素开始入手。此时,又没有LoginForm.js
文件或者LoginForm.scss
文件 。故而,他不得不求助于grep
这些工具或者靠猜测去找到相关代码文件。也就是说,如果这个登录表单需要一个独立的命名空间,我们就需要将其放在一个独立的组件中。而这种一致性在工程项目中具有重要的价值,因为它避免了猜测查找.
5. 防止在组件外定义样式
我们已经展示了我们常用的命名规则,现在我们想将这些规则应用到UI组件上。如果所有的组件都只使用了附有独特命名空间前缀的类名, 我们敢说这些样式绝对不会和它人的重合。 从下面会涉及到的注意事项中不难看出这一方法的意义性。但是一遍遍重复的编写这些命名空间确实会让人觉得厌烦。
一个行之有效且非常便捷的方法便是将文件中所涉及到的全部样式放在一个标有前缀名的块中。注意我们是怎么只输入一次app或者组件所需要重复使用的名字的:
.myapp-Header { background: black; color: white; &-link { color: blue; } &-signup { border: 1px solid gray; }}
虽然上面的例子都是运用在SASS中的,但是喜人的是