我们为什么要写组件呢?这里不细分组件、插件、控件,追究其原因无非让代码,能够复用,追求更快的开发效率。其实还有个重要的原因,项目大了之后,难以维护。这个时候就会把项目中重复的部分抽取出来,形成一个组件。但是组件也会有些’缺点’,这个最后讲。
组件需求
要实现如图的一个条件选择器
有的时候,项目时间紧张,就会直接切图,通过jquery的dom选择器实现这个’简单的功能’。
需求分析
为了更好的维护,以及更好的复用此组件,就要做些抽象。
- 数据层:用来决定按钮个数以及按钮是否选择
- 表现层:按钮使用现有的ui组件
- 逻辑层:按钮事件等逻辑处理
数据层
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
data: null, choseT: 0, choseF: 0, getDataStatistics: function() { var list = this.data; var choseT = 0; var choseF = 0; var len = list.length; for (var i = 0; i < list.length; i++) { if(list[i].checked == 'checked') { choseT++; }else { choseF++; } } return { choseT: choseT, choseF: choseF, len: len }; }, dataChangeAll: function(checked) { var list = this.data; var len = list.length; checked = checked || ''; if(checked == 'checked') { this.choseT = len; this.choseF = 0; }else { this.choseT = 0; this.choseF = len; } for (var i = 0; i < len; i++) { list[i].checked = checked; } }, dataChangeSingle: function(index, checked) { var list = this.data; var choseT = this.choseT; var choseF = this.choseF; if(checked == 'checked') { choseT++; choseF--; }else { choseT--; choseF++; } this.choseT = choseT; this.choseF = choseF; list[index].checked = checked; } |
数据层主要对原始数据做些CURD的一些操作,具体的操作看具体的业务需求,但是要具有这个意识。
表现层
说白了表现层也就是template层或者view层,就是用户所看到的,一般会用一个比较成熟的ui库,比如bootstrap。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
getHtml: function(list, statistic) { var html = ['<div class="sales-dialog">', '<div>', '<div class="tag-box-chose J_view_checkNav">', this.getChoseNav(statistic), '</div>', '<div class="mt_10 J_view_checkItems">', this.getChoseItem(list), '</div>', '</div>', '</div>'].join(''); return html; }, getChoseNav: function(statistic) { var checkAll = ''; var checkNone = ''; var len = statistic.len; if(statistic.choseT == len) { checkAll = 'checked'; } if(statistic.choseF == len) { checkNone = 'checked'; } return [ '<label class="tag '+checkAll+'">', '<input type="radio" name="radio-grade input-fat" class="J_view_checkAll" '+checkAll+' />', '<span class="tag-tit">全选</span>', '</label>', '<label class="tag '+checkNone+'">', '<input type="radio" name="radio-grade" class="J_view_checkNone" '+checkNone+'/>', '<span class="tag-tit">全不选</span>', '</label>' ].join(''); }, getChoseItem: function(list) { var inputs = ''; var doInputFunc = function(i, detail) { return [ '<div style="display:inline-block;width:150px;">', '<label data-toggle="checkbox" class="checkbox-pretty inline '+detail.checked+'">', '<input type="checkbox" value="'+i+'" class="J_view_checkItem " '+detail.checked+'><span>'+detail.name+'</span>', '</label>', '</div>', ].join(''); }; for (var i = 0; i < list.length; i++) { inputs += doInputFunc(i, list[i]); } return inputs; }, domAction: function($el, type, data) { var html = ''; type = type || 'all'; if(type == 'item') { html = this.getChoseItem(data); $el.find('.J_view_checkItems').html(html); }else if(type == 'all') { html = this.getChoseNav(data); $el.find('.J_view_checkNav').html(html); } } |
众所周知,template就是根据数据渲染成html,在spa项目尤其重要。
逻辑层
这层主要做 调用template方法将数据渲染到页面上;将页面上的一些事件结果,映射到数据层。其实现在流行的MVVM模式,就是在逻辑层这里做了更多的事情,只是开发者们不用去关心细节处理,更专注业务的开发。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
eventBind: function($el) { var _this = this; var $target = |