Fashion

前言

在Sencha Cmd 6.0, 我们很高兴的向大家介绍一种新颖快速开发 Ext JS 6.0 主题样式的工具,名叫“Fashion”. 结合使用 Fashion 和 sencha app watch 成为了一种新的主题样式开发模式,我们称之为“实时更新”.

“实时更新”使用 Fashion 编译注入最新的 CSS 到你正在运行的页面里. 这意味着,你不必重新加载 CSS 文件去看样式更改,而是近乎实时的就可以直接在浏览器里看到样式的更改效果.

当为 Ext JS 6 的应用编译样式的时候,Sencha Cmd 6也使用了 Fashion。由于 Fashion 是在 JavaScript 里实现的,所以不在依赖 Ruby.

什么是 Fashion?

Fashion 是一个 .scss 的编译器,用于生成 CSS. Fashion 也加入了一些 Sass 没有的新特性,这些新特性允许像 Sencha 检查器这样的工具可以直观的检查和编辑定义在主题样式里的变量(或者你程序里的变量).

JavaScript 扩展

通过编写 JavaScript 模块,用户可以扩展 Fashion 的功能. 一般来讲, Ext JS 用户都比较熟悉 JavaScript, 所以扩展行为应该比扩展 Compass 简单。下面我们将介绍更多关于扩展 Fashion 的内容.

现在言归正传, 让我们来一起聊聊 Fashion!

兼容性

Fashion 兼容 CSS3 语法以及大多数的 sass-spec 验证套件. 因为 Fashion 理解大多数的Sass代码, 获取存在的 .scss代码, 用 Fashion 去编译应该不是什么难事。

不过, 由于一些额外的特性(稍后会讨论到), 说 Fashion “是 Sass 的一种实现”或者 Fashion 编译的语言“是Sass”是不正确的。有许多地方,Sass 这个单词经常被用于配置项名字或者磁盘目录。考虑到兼容性, 这些配置项仍旧命名为 Sass, 尽管下面的语言不是严格意义上的 Sass.

使用实时更新

你可以在主流浏览器里打开应用,你会发现加载的是 Sass 文件而不是 CSS。Fashion 可以监控文件改动并重新编译 Sass 文件,并更新 CSS 而不需要重新加载页面。

有两种方式可以让 sencha app watch启用 Fashion.

你可以编辑app.json中的“development”对象

...
"development": {
    "tags": [
        "fashion"
    ]
},
...

另外一种, 你可以在加载的页面URL中加上 “?platformTags=fashion:1”

现在我们准备运行:

  • 在你的项目根路径执行 “sencha app watch” .
  • 浏览器导航到你的应用程序 (例如, http://localhost:1841/app).

现在你可以更改主题样式变量,应该几乎马上就能看到更改后的效果了。

备注: 只有从 Cmd WEB 服务器上查看页面时,才会实时更新。在 Ext Js Classic toolkit 里, 某些 Sass 的更改需要一次重新布局或者刷新整个页面才生效。在 Modern toolkit 里,这不是个问题,因为它更多地基于 CSS3 和自适应一些未知的变化.

语言扩展

动态变量

在Fashion里, 动态变量扮演着很重要的一部分. 动态变量跟普通的变量非常相似,但动态变量的值被包裹在“dynamic()”里. 动态变量和普通变量的不同之处正是它们之间如何交互. 请看下面代码

$bar: dynamic(blue);

$foo: dynamic($bar);  // 注意 $foo 依赖 $bar

$bar: dynamic(red);

@debug $foo;  // red

注意 $foo$bar计算得来. 这种依赖被 Fashion 特殊处理, $foo 的计算会延迟到$bar 的最终结果被确定之后.

换而言之, 动态变量有两次处理过程:赋值 和 计算.

赋值

动态变量, 跟普通变量一样, 都是通过普通的“瀑布流”的顺序赋值的(不像 !default):

$bar: dynamic(blue);

$bar: dynamic(red);

@debug $bar;  // red

这使得工具可以将自定义值添加到任何代码块, 并控制它们的动态变量.

给动态变量赋值只会在文件范围内有效,并且要放在控制结构语句之外。比如, 这是非法的:

$bar: dynamic(blue);

@if something {
    $bar: dynamic(red); // 非法
}

替换上面的写法, 应该这样写:

$bar: dynamic(if(something, red, blue));

为确保值的计算以及下面即将讨论的变量提升,这种书写要求是必要的。

动态变量可以在它们声明(不管有没有dynamic())之后赋值.

$bar: dynamic(blue);

$bar: red;  // 重新给 $bar 赋值 red

$bar: green !default;  // 重新给 $bar 赋值 green

@debug $bar;  // green

没有“default dynamic”这种东西.

计算

动态变量根据依赖顺序计算, 而不是变量声明顺序. 声明顺序仅适用于级联的单个变量赋值. 看上面的例子即可明白. 这种顺序同时意味着,即使我们移除第一个 $bar的设置,其最终也是相同结果。

考虑更复杂的例子:

$bar: dynamic(mix($colorA, $colorB, 20%));

$bar: dynamic(lighten($colorC, 20%));

$bar 原表达式使用$colorA$colorB. 如果那是 $bar唯一的一次赋值, 那么$bar会依赖这两个变量计算结果。不过此处$bar 被重新赋值,紧接只用了$colorC, 最终, $bar 仅依赖 $colorC. $bar最初的那次赋值可能永远不会发生。

变量提升(Hoisting)

为了完成这一切, 在任何其它Sass代码执行之前,Fashion 会收集所有动态变量并且计算他们的值. 换而言之, 类似于 JavaScript 变量, 动态变量会被提升到顶部.

提升(Elevation)

当用某些变量给动态变量赋值时, 这些变量就已经被提升为动态变量.

$foo: blue;

$bar: dynamic($foo);

即使 $foo被声明成普通变量, 但由于 $bar 使用了 $foo, Fashion 将 $foo 提升到了动态变量.

备注: 这也同时表明 $foo 必须服从动态变量的规则.

当从旧版本 Sencha Cmd 移植, 已经最大限度支持这种行为了. 当普通变量被提升至动态变量, 会产生警告. 在接下来的发布, 这个警告会变成一个错误. 我们推荐尽可能的用dynamic()声明变量.

扩展 - 需要 JavaScript

你可以通过编写 JavaScript 代码扩展 Fashion. 引用这些来自Sass的代码需要使用require(). 例如:

require("my-module");

// or

require("../path/file.js"); // relative to scss file

在内部, Fashion 使用 ECMAScript 6 (ES6) System.import API (或者SystemJSpolyfill) 去支持加载标准的 JavaScript 模块.

用 pre-ES6 语法写一个模块可以这样写:

exports.init = function(runtime) {
    runtime.register({
        magic: function (first, second) {
            // ...
        }
    });
};

使用 SystemJS, 你可以启用“transpilers”来在任何浏览器中编写 ES6 代码 . 在 ES6 中写法如下:

module foo {
    export function init (runtime) {
        runtime.register({
            magic: function (first, second) {
                // ...
            }
        });
    }
}

升级

动态变量

当升级到 Ext JS 6, 动态变量的内部用法会影响这些变量如何在应用程序或者自定义主题里赋值. 尽管不是必要的, 我们推荐你使用 !dynamic 改变变量的值. 多数情况下可以不加思索的用 dynamic() 替换 !default (早前发布版本的方法):

// before:

$base-color: green !default;

// after:

$base-color: dynamic(green);

动态变量赋值更严格,如果有错误也会更加容易发现.

Compass 扩展

Compass 依赖 Ruby 代码的功能将不再支持,因为已经不用 Ruby 了. 同样的功能已经用 JavaScript 代替了. 在许多情形下,在 JavaScript 中使用 require() 实现这些缺失的功能. 不管怎样,部分来自 Compass 的 Sass 代码,已经包含在 Fashion 里,所以并不是所有的 Compass 功能会被影响. 一般来讲, 如果你没有使用任何自定义或者基于 Ruby 的 Compass 功能,你将可能不需要作任何变动.

结语

Fashion 令我们非常兴奋,希望你们也一样! 改变你的应用程序的主题样式从未如此简单, 并且现在可以使用和框架一样的语言来扩展 Sass. 请务必在论坛给我们留下反馈.

最新更新