Brix 组件初探

板砖是怎样炼成的

首页 Brix 介绍 所言,Brix 是一淘 UX 部门将前端工作平台化的努力成果, 它的目的 是让后端能够快速扩展组件模板代码来完成实际项目需求, 而前端工程师只需要完成通用组件、提供组件 DOM 结构模板即可。详细的技术思想,请看 Brix Framework 简介

本文的目的是,让前端工程师能够快速上手,开发 Brix 组件;告诉你,一块板砖(Brick)是如何炼成的。

Brix 框架中,在 PC 端与移动端所采用的技术结构有所不同。PC 端网络限制较小,浏览器也更宽容,性能差别也更大, 因此选择了 KISSY 作为基础框架;而移动端的选择则是 SeaJS 与修改过的 ZeptoJS。 本文目前仅讨论 KISSY 部分。

模块与继承

一个合格的组件必须是 KISSY 模块。我们使用 KISSY 1.2 作为基础,它提供了类似 RequireJS、SeaJS 等的模块加载机制。详情可以看 KISSY Loader 文档,在这里我们只做简要说明。简要的模块封装代码如下:

KISSY.add('module-name', function(S, Dependency1, Dependency2) {
    function Module() {}

    // 暴露出模块,一个构造函数
    return Module;
}, {
    // 模块的依赖,会作为工厂函数的参数传递进去
    requires: ['module-dependency1', 'module-dependency2']
})

文件组织

首先要搞清楚的是模块名。假设你的组件名叫做 Keystone, 在 Brix 中,它的代码应该这么放:

brix
├── demo
│   └── gallery
│       └── keystone
│           ├── keystone.html
│           └── keystone.less
└── src
    └── gallery
        └── keystone
            └── index.js

demo/gallery/keystone/ 目录,用来放置你的组件的演示文件,以及相关的样式。样式不强制用 LESS 来写。 src/gallery/keystone/ 目录则用来放置组件相关的代码,入口是 index.js,其他模块酌情添加。

demo

demo/gallery/keystone/keystone.html 的应该长这样:

<!DOCTYPE HTML>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>Brix Keystone Demo</title>
  <link rel="stylesheet" type="text/css" href="../../../dist/brix.css">
  <script src="http://a.tbcdn.cn/s/kissy/1.2.0/kissy.js"></script>
  <script src="../../config.js"></script>
</head>
<body>
  <!-- 组件相关的 HTML 代码 -->
  <script type="text/javascript">
KISSY.ready(function(S) {
    KISSY.use('brix/gallery/keystone/', function(S, Keystone) {
        var keystone = new Keystone({
            // config
        });
    });
});
  </script>
</body>
</html>

继承自 Brick

所有的 Brix 组件都继承自 core/brick, 拱顶石(Keystone)虽然是建筑设计里最重要的板砖(Brick),但毕竟还是板砖。所以,它要继承 Brick

KISSY.add('brix/gallery/keystone/', function(S, Brick) {
    function Keystone() {
        Keystone.superclass.constructor.apply(this, arguments);
    }
    S.extend(Keystone, Brick, {
        // 此处定义 keystone 自己的方法
    });
}, {
    requires: ['brix/core/brick']
});

使用组件的方式

我们先给 Keystone 加点功能:

KISSY.add('brix/gallery/keystone/index', function(S, Brick) {

    function Keystone() {
        Keystone.superclass.constructor.apply(this, arguments);
    }

    // 在组件加载、渲染完毕之后,对组件节点内的 p 做动画。
    S.extend(Keystone, Brick, {
        initialize: function() {
            var el = this.get('el'),
                cfg;

            cfg = {
                duration: 2,
                queue: 'keystone'
            };
            el.all('p').animate({
                backgroundColor: '#f50'
            }, cfg).animate({
                backgroundColor: '#fff'
            }, cfg);
        }
    });

    return Keystone;
}, {
    requires: ["brix/core/brick"]
});

它的功能很简单,给组件节点里的每个 <p> 进行动画,背景色变橙再变白。要怎么用这个组件呢?

方式一:直接构建

HTML 代码如下:

<div id="keystone1">
  <p>Hello <span>World</span></p>
</div>

我们可以直接 new Keystone 来初始化这个组件:

KISSY.use('brix/gallery/keystone/', function(S, Keystone){
    new Keystone({
        el: '#keystone1'
    });
});

方式二:让 Pagelet 代劳

HTML 代码如下:

<div id="container2">
  <div id="keystone2" bx-name="keystone">
    <span>Hello <span>World</span></span>
  </div>
</div>

将整个 #container2 节点作为一个页面,让 Pagelet 去解析节点树中引用了 Brix 组件的节点, 并在加载好相应的 Brix 组件模块代码之后,将这些节点作为源节点交给相应的组件初始化。

在此例中,Pagelet 通过 bx-name 参数找到 helloworld 同时根据其 path 设定,加载 helloword

KISSY.use('brix/core/pagelet',function(S,Pagelet){
    var pagelet = new Pagelet({
        tmpl: '#container2'
    });
    pagelet.addBehavior();
});

两种加载方式的实际效果:

小结

现在你应该知道该如何动手写并使用自己的 Brix 组件了。接下来,我们通过逐步完善 Keystone, 来了解 Brix 都提供了哪些方便组件开发与使用的特性。