组件开发规范

如何开发一个 Brix 组件

基本要求

本文列出 Brix 组件的开发约定,并对一些设计决定作解释。更简易的开发入门,请看 Brix 组件入门

粗略地说,一个合格的 Brix 组件需要符合一下要求:

  • 使用 KISSY.add 方式声明模块
  • 继承自 Brick

KISSY 模块

在 PC 端,Brix 采用 KISSY 作为基础框架,并将组件代码以 KISSY Loader 所规范的模块形式划分。 因此,Brix 组件代码需要遵从以下范式:

KISSY.add('brix/gallery/my-brick/', function(S) {
    // 组件构造函数
    function MyBrick() {}

    // 输出构造函数
    return MyBrick;
});

继承自 Brick

Brick 提供了 Brix 中组件的生命周期、事件代理等机制,因此,符合 Brix 组件规范的 JavaScript 组件,应继承自此类。

KISSY.add("brix/gallery/dropdown/", function(S, Brick) {
    function Dropdown() {
        // 调用父类的构造函数
        Dropdown.superclass.constructor.apply(this, arguments);
    }
    // 继承
    S.extend(Dropdown, Brick, {
        // 这里写私有方法
    });
    return Dropdown;
}, {
    // 依赖 brix/brick
    requires: ["brix/brick"]
});

在余下的文档中,为了简略起见,省去了外层的模块封装代码:

KISSY.add('my-brick', function(S, Brick) {
    // 模块代码
}, {
    requires: ['brix/brick']
});

请各位注意。

ATTRS:配置项

我们在 Brick 中引入了 KISSY 的 Base 做配置项管理。 如果你的 Brix 组件需要提供配置项,则可以很方便地使用 MyBrick.ATTRS 来定义属性、默认值以及它们的 gettersetter 等。

MyBrick.ATTRS = {
    // 同 KISSY 的 Base 写法
    passphrase: {
        value: "my precious...",
        setter: function(v) {
            if (v && v.length >= 6) {
                return v;
            }
        }
    }
};

S.extend(MyBrick, Brick, {
    initialize: function() {
        // 使用 this.get 来获取属性值
        var passphrase = this.get('passphrase');
    }
});

RENDERERS:模板渲染扩展方法

MyBrick.RENDERDERS = {
    currency: {
        dollar: function(num) {
            return "$" + num;
        }
    }
};

DOCEVENTS:代理在 document 上的事件行为

如果选择器为空,则直接绑定事件在 document 上

Dropdown.DOCEVENTS = {
    "body": {
        click: function(e) {
            var self = this;

            if (!self.__show) {
                var el = self.get('el');
                el.all('.dropdown-list').css('display', 'none');
                el.all('.dropdown-a').removeClass('dropdown-aactive');
            }
            self.__show = false;
        }
    }
}

EVENTS:代理在组件节点上的事件行为

如果选择器为空,则直接绑定事件在节点上

Dropdown.EVENTS = {
    ".dropdown-a": {
        click: function(e) {
            var el = this.get('el').one('.dropdown-list');
            this.__show = true;
            if (el.css('display') == 'block') {
                this.blur();
            } else {
                this.focus();
            }
        },
        mouseenter: function(e) {
            var currentTarget = S.one(e.currentTarget);
            currentTarget.addClass('dropdown-ahover');
        },
        mouseleave: function(e) {
            var currentTarget = S.one(e.currentTarget);
            currentTarget.removeClass('dropdown-ahover');
        }
    }
};

METHODS:扩展对外方法

Dropdown.METHODS = {
    focus: function() {
        var el = this.get('el');
        el.one('.dropdown-list').css('display', 'block');
        el.one('.dropdown-a').addClass('dropdown-aactive');
    },
    blur: function() {
        var el = this.get('el');
        el.one('.dropdown-list').css('display', 'none');
        el.one('.dropdown-a').removeClass('dropdown-aactive');
    }
}
S.augment(Dropdown, Dropdown.METHODS);

FIRES:触发自定义事件

使用 KISSY 自有的事件触发方式:

this.fire('selected', data);

Brix 对组件触发的自定义事件名称、个数不做限制,但是写组件的同学一定要在组件相关文档中描述清晰。 同时,也可以在组件代码中声明 FIRES 对象来声明组件会触发的自定义事件列表:

MyBrick.FIRES = {
    hovered: 'hovered',
    activated: 'activated'
};

但这个对象不是必须的,并无实际作用。