iuap-design/blog

NeoUI 的控件机制

bluemind7788 opened this issue · 0 comments

NeoUI 的控件机制

在前端的控件领域,现在基本分为了两大阵营:以bootstrap为代表的阵营和以jquery插件、ant design为代表的阵营。bootstrap阵营的特点是以样式为主,功能性的控件很少,它们主要解决了前端开发中的样式问题。jquery插件、ant design的特点是功能性的控件比较多,通过参数控制的方式来定制用户需求控件。
NeoUI和它们有什么不同之处呢?

  • NeoUI将控件功能机制和样式机制分开。
  • 控件功能可以通过控件继承扩展、控件组合、控件嵌套、自定义控件来定制开发自己需要的控件。
  • 控件样式可以通过定制主题、辅助类、覆盖类方式来实现的样式。

1 控件功能

控件继承扩展机制

iuap 底层的控件都通过u.命名空间来标识,在项目上如果要扩展底层控件,可以通过继承的方式。
举一个例子,在电子销售项目中,其命名空间定义为ec,页签控件需要鼠标滑过时就切换,底层控件仅支持点击切换。这样我们通过u.Tabs.extend来继承底层控件,添加鼠标经过事件,注册控件。

ec.Tabs = u.Tabs.extend({
    init: function(){
        var self = this;
        u.Tabs.prototype.init.call(this);

        this.element.querySelectorAll('.u-tabs__tab').forEach(function(node) {
            u.on(node, 'mouseenter', self._tabHover.bind(self));
        })
    },
    _tabHover: function (e) {
        var href = e.target.href.split('#')[1];

        this.show(href);  
    }
});

u.compMgr.regComp({
    comp: ec.Tabs,
    compAsString: 'ec.Tabs',
    css: 'ec-tabs'
})

控件组合

在一般情况下,一个html元素对应的是一个控件。但是,有的时候也需要一个html元素对应多个控件。
如下面的html元素是一个下拉框也需要是一个普通的输入框,这样才能有普通输入框的点击效果。

<div class="u-combo u-text" style="width: 200px" id="combo2">
    <input class="u-input"/>
    <label class="u-label"></label>
    <span class="u-combo-icon" data-role="combo-button"></span>
</div>

控件嵌套

控件嵌套是在控件里面包含的不仅仅是html元素,也可以是一个控件。
如下面的例子中gatherComp 就是AttrSelector中包含的控件。

ec.AttrSelector = u.BaseComponent.extend({
    init: function(){
        var self = this;
        this.shopProdType = this.options.shopProdType;
        this.gatherComp = this.element.querySelector('#attrGather')['u.Combo'];
        this.allComps = [];
        //监听属性集Combo点击事件
        //如果已选择最末级店铺分类,则根据店铺内分类获取属性集;否则提示用户选择最末级店铺分类
         this.gatherComp.on('ec.combo.beforefocus', function() {
            //说明:查询所有属性集,不再根据店铺分类过滤
            $.ajax({
                type: 'post',
                url: G.API.PRODUCT.CREATE.getAttrGatherByClassify,
                contentType: 'application/json; charset=utf-8',
                dataType: 'json',
                success: function(data) {
                    var prodAttrGatherOpt = self._dataconvert(data.prodAttrGathers, "attrGatherName", "id"); 
                    self.gatherComp.setComboData(prodAttrGatherOpt);
                }
            });
         });

    }
});

u.compMgr.regComp({
    comp: ec.AttrSelector,
    compAsString: 'ec.AttrSelector',
    css: 'ec-attrselector',
    dependencies: ['ec.Combo']
})

自定义控件

自定义控件的例子见上面的例子。