Skip to content

Latest commit

 

History

History
215 lines (181 loc) · 5.88 KB

模块化与组件化.md

File metadata and controls

215 lines (181 loc) · 5.88 KB

返回目录

模块化与组件化

在静态类型语言 Java 与动态类型语言 Python 中都有内建的模块机制,模块机制能够让我们更好地去

import java.awt.*;
import java.awt.color.*;
$.browser.msie = function detectIE() {};

模块一般指能够独立拆分且通用的代码单元。

Mixing and matching generic components is what modern web development is all about.

The terms are similar. I generally think of a "module" as being larger than a "component". A component is a single part, usually relatively small in scope, possibly general-purpose. Examples include UI controls and "background components" such as timers, threading assistants etc. A "module" is a larger piece of the whole, usually something that performs a complex primary function without outside interference. It could be the class library of an application that provides integration with e-mail or the database. It may be as large as a single application of a suite, such as the "Accounts Receivable module" of an ERP/accounting platform.

I also think of "modules" as being more interchangeable. Components can be replicated, with new ones looking like old ones but being "better" in some way, but typically the design of the system is more strictly dependent upon a component (or a replacement designed to conform to that component's very specific behavior). In non-computer terms, a "component" may be the engine block of a car; you can tinker within the engine, even replace it entirely, but the car must have an engine, and it must conform to very rigid specifications such as dimensions, weight, mounting points, etc in order to replace the "stock" engine which the car was originally designed to have. A "module", on the other hand, implies "plug-in"-type functionality; whatever that module is, it can be communicated with in such a lightweight way that the module can be removed and/or replaced with minimal effect on other parts of the system. The electrical system of a house is highly modular; you can plug anything with a 120V15A plug into any 120V15A receptacle and expect the thing you're plugging in to work. The house wiring couldn't care less what's plugged in where, provided the power demands in any single branch of the system don't exceed safe limits.

模块化无疑是 ES6 中最令人激动的特性,保证了大型应用程序的健壮性、可扩展性与可重构性

模块化 CSS

命名规范

.block{} // the ‘thing’ like .list
.block__element{} // a child of the block like .list__item
.block--modifier{} // a variation of the ‘thing’ like .list-—vertical

预处理器

为了继续遵循 BEM 规范,我们需要在 SCSS 中添加对于父元素的引用,大概是如下语法形式:

.block {
  @at-root #{&}__element {
  }
  @at-root #{&}--modifier {
  }
}

最终编译生成的结果为:

.block {
}
.block__element {
}
.block--modifier {
}

而在 SASS 3.3 之后,我们可以使用如下的快捷写法:

.block {
  &__element {
  }
  &--modifier {
  }
}

在真实的开发环境中,我们以一个典型的导航栏为例描述下应该如何使用 BEM 规范:

<nav role="navigation" aria-label="primary">
  <ul class="nav__list">
    <li class="nav__list__item">
      <a href="" class="nav__link"></a>
    </li>
    <li class="nav__list__item">
      <a href="" class="nav__link--active"></a>
    </li>
    <li class="nav__list__item">
      <a href="" class="nav__link"></a>
    </li>
  </ul>
</nav>

我们编写的 CSS 样式如下所示:

nav[role='navigation'] {
}
.nav {
  &__list {
    &__item {
    }
  }
  &__link {
    &--active {
    }
  }
}

最终的输出结果大概是这个样子:

nav[role='navigation'] {
}
.nav {
}
.nav__list {
}
.nav__list__item {
}
.nav__link {
}
.nav__link--active {
}

CSS-in-JS

广义上说,目标格式为 CSS 的 预处理器 是 CSS 预处理器,但本文 特指 以最终生成 CSS 为目的的 领域特定语言。Sass 、 LESS、Stylus 是目前最主流的 CSS 预处理器。

.opacity(@opacity: 100) {
  opacity: @opacity / 100;
  filter: ~'alpha(opacity=@{opacity})';
}

.sidebar {
  .opacity(50);
}

将以上 DSL 源代码 (LESS),编译成 CSS:

.sidebar {
  opacity: 0.5;
  filter: alpha(opacity=50);
}

取到 DSL 源代码 的 分析树将含有 动态生成 相关节点的 分析树 转换为 静态分析树将 静态分析树 转换为 CSS 的 静态分析树将 CSS 的 静态分析树 转换为 CSS 代码

.foo {
  transition: width 0.3s;
}

自动按需生成前缀

.foo {
  -webkit-transition: width 0.3s;
  -moz-transition: width 0.3s;
  -o-transition: width 0.3s;
  transition: width 0.3s;
}
/* 变量 */
:root {
  --fontSize: 14px;
  --mainColor: #333;
  --highlightColor: hwb(190, 35%, 20%);
}
/* 自定义 media queries */
@custom-media --viewport-medium (min-width: 760px) and (max-width: 990px);
/* 变量引用 以及使用 calc() 运算*/
body {
  color: var(--mainColor);
  font-size: var(--fontSize);
  line-height: calc(var(--fontSize) * 1.5);
  padding: calc((var(--fontSize) / 2) + 1px);
}
/* 颜色处理函数 */
a {
  color: color(var(--highlightColor) blackness(+20%));
  background: color(red a(80%));
}
/* 使用自定义 media queries */
@media (--viewport-medium) {
  .foo {
    display: flex;
    font-size: calc(var(--fontSize) * 2 + 6px);
  }
}
/* 变量 */
/* 自定义 media queries */
/* 变量引用 以及使用 calc() 运算*/
body {
  color: #333;
  font-size: 14px;
  line-height: 21px;
  padding: 8px;
}
/* 颜色处理函数 */
a {
  color: rgb(89, 142, 153);
  background: rgba(255, 0, 0, 0.8);
}
/* 使用自定义 media queries */
@media (min-width: 760px) and (max-width: 990px) {
  .foo {
    display: -webkit-box;
    display: -webkit-flex;
    display: -ms-flexbox;
    display: flex;
    font-size: 34px;
  }
}