如何让程序员更容易的开发Web界面,是一个持久的话题,所有的从事相关开发的公司都会碰到这个问题,并且被这个问题所深深困扰。
Tiny框架也不得不直视这个问题,确实来说,想解决这个问题,也是非常有难度与深度的,业界也有各种各样的尝试,这也是有各种各样不同框架出现的原因。 Tiny框架构建者认为,完全采用一种框架解决所有问题,是不现实的。而且即使目前找得到一种非常好的框架,暂时可以满足应用需要,但是随着技术的发展,业务的进化,就会慢慢变得不再满足业务需要。因此,Tiny框架构建从不再把做一套UI组件去适各种需求作为自己的目标。 反过来,我们看看在做Web应用中,可能会碰到的问题:- UI中JS的引入与顺序,JS合并的问题
- UI中css的引入与顺序,CSS合并的问题
- UI中碰到性能问题时的影响范围,比如:一个树出现问题,要改动许多用到树的地方
- 代码重复的问题,同样的内容在许多地方都有,如果要改动就要改动许多个地方
- 整体布局调整困难的问题
- 程序员需要关注的内容太多的问题,JS,CSS,布局,后台业务,前台展现,尼玛界面工程师必须得是全才才可以搞得定所有问题。
- 开发效率的问题
- 执行效率的问题,前台响应要求速度更快
- 集群的问题
- 国际化的问题
- ...
因此,我在以前写过一篇文章:感兴趣的同学,可以去看看,今天的目标是利用TinyUI框架的重构SmartAdmin,使得更容易被使用。
SmartAdmin初识 SmartAdmin是一套基于JQuery,Bootstrap构建的UI组件库,说直白些,它就是个大杂烩,它把各种JQuery插件和Bootstrap整合到一起,提供了一整套基本完整的应用开发UI库,基本是拿着它就可以用来非常专业的应用系统了。 下面是界面,当然它内嵌提供了四套皮肤,可以进行切换的:![](http://web.j2ee.top/data/attachment/forum/201505/27/223229mf3jiqszbxxxtjwd.jpg)
由于SmartAdmin是商业产品,需要购买,因此不能提供其Copy,据说在Baidu可以搜到,据说可以下载。如果只是想看一下的话,请点击此链接: SmartAdmin分析 通过对SmartAdmin的分析,发现其复用了大量的开源插件,并且利用了Ajax加载技术,在运行期加载了大量的JS插件或CSS,整个页面采用Html+JS整合而成,许多JS与页面还是分离的,也就是说对本页面中的Dom元素的处理的JS不一定在当前html文件中,所以要想看得懂是非常困难的,如果想把它应用在自己的项目当中,也是非常困难的一件事情。 举个例子来说,要显示一个小部件,需要写这么一段内容:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647 | <div class="jarviswidget" id="wid-id-0"><!-- widget options:usage: <div class="jarviswidget" id="wid-id-0" data-widget-editbutton="false"> data-widget-colorbutton="false" data-widget-editbutton="false"data-widget-togglebutton="false"data-widget-deletebutton="false"data-widget-fullscreenbutton="false"data-widget-custombutton="false"data-widget-collapsed="true" data-widget-sortable="false" --><header><h2><strong>Default</strong> <i>Widget</i></h2> </header><!-- widget div-->< div> <!-- widget edit box -->< div class="jarviswidget-editbox"><!-- This area used as dropdown edit box -->< input class="form-control" type="text"><span class="note"><i class="fa fa-check text-success"></i> Change title to update and save instantly!</span> </div><!-- end widget edit box --> <!-- widget content -->< div class="widget-body"> <p> Widget comes with a default 10 padding to the body which can be removed by adding the class <code>.no-padding</code> to the <code>.widget-body</code> class. The default widget also comes with 5 widget buttons as displayed on top right corner of the widget header. </p><a href="javascript:void(0);" class="btn btn-default btn-lg"> <strong>Big</strong> <i>Button</i> </a> </div><!-- end widget content --> </div><!-- end widget div --> < /div> |
这个程序员处理起来还是相当有难度的,好吧,这还不算过分的。 执行下面的命令: dir *.js /s /w运行结果:
12 | 所列文件总数: 310 个文件 6,043,053 字节 |
执行下面的命令: dir *.css /s /w运行结果:
12 | 所列文件总数: 36 个文件 1,511,412 字节 |
里面有这么多的JS,有这么多的CSS,它们的引入顺序也是非常重要的,稍有差错,就会有js错误的问题。 再来看看,JS加载过程:
可以看到,要访问大量的js,CSS,对于服务器的压力是比较大的,客户端加载时间也是比较长的,程序员要厘清这些关系,也是非常困难的。 SmartAdmin重构 对SmartAdmin重构,是指按照Tiny框架的体系结构来进行重构。 第一步,厘清关系 通过整理,发现smartadmin中使用的js插件有如下之多:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253 | bootstrapbootstrapProgressbarbootstrapSliderbootstrapTagsbootstrapTimepickerbootstraptreebootstrapWizardckeditorcolorhelperscolorpickerdatatablesdelete-table-rowdropzoneeasyPieChartexcanvasfastclickflotFontAwesomefueluxwizardfullcalendarie-placeholderion-sliderjqueryjquery-formjquery-nestablejquery-touchjqueryuijqueryvalidatejs-migratejstorageknobmarkdownmaskedInputmaxlengthmorrismsieFixmultiselectnotificationnoUiSliderpaceprettifyraphaelselect2selectToUISlidersmartadminsmartwidgetssparklinesummernotesuperboxthrottle-denouncetypeaheadvectormapx-editable |
第二步:UI插件,组件包化: 比如JQuery组件包化,就是编写下面的文件:jquery.ui.xml
12345 | <ui-components> <ui-component name="jquery"> <js-resource>/jquery/jquery-1.11.0.js</js-resource> </ui-component>< /ui-components> |
比如JQueryUI组修的包化,就是编写下面的文件:jqueryui.ui.xml
123456 | <ui-components> <ui-component name="jqueryui" dependencies="jquery"> <js-resource>/jqueryui/js/jquery-ui-1.10.4.custom.js</js-resource> <css-resource>/jqueryui/css/smoothness/jquery-ui-1.10.4.custom.css</css-resource> </ui-component>< /ui-components> |
比如BootStrap组件包化,就是写下面的文件:bootstrap.ui.xml
123456 | <ui-components> <ui-component name="bootstrap" dependencies="jqueryui"> <css-resource>/bootstrap/css/bootstrap.min.css</css-resource> <js-resource>/bootstrap/js/bootstrap.js</js-resource> </ui-component>< /ui-components> |
其它类推,最主要的目的就是要分清,用到哪些JS,哪些CSS,并且整理组件包之间的依赖关系,比如,上面BootStrap就依赖了jqueryui,当然jqueryui依赖了JQuery 通过上面的依赖树Tiny框架就可以自动构建好CSS及JS资源。 因为这些资源都是放在Jar工程的main/resources目录中,因此就直接打进jar包了。 第三步,编写宏 比如,原来的Tab,需要涉及到html,js,编写后续使用的宏如下:
123456789101112131415161718192021222324252627282930313233343536 | #*** JqueryUI Tab* juiTab[1..1]* juiTabHeader[1..1]* juiTabHeaderItem[1..n]* juiTabContentItem[1..n]*##macro(juiTab $juiTabId)< div id="$juiTabId">$bodyContent< /div>< script> $(document).ready(function(){ $('#$juiTabId').tabs(); });< /script>#end#macro(juiTabHeader)< ul>$bodyContent< /ul>#end#macro(juiTabHeaderItem $juiTabContentItemId)< li> <a href="#$juiTabContentItemId">$bodyContent</a>< /li>#end#macro(juiTabContentItem $juiTabContentItemId)< div id="$juiTabContentItemId">$bodyContent< /div>#end |
以后的程序员就可以以如下方式编写一个Tab页了:
12345678910111213141516 | #@juiTab("tabs") #@juiTabHeader() #@juiTabHeaderItem("tabs-a")First#end #@juiTabHeaderItem("tabs-b")Second#end #@juiTabHeaderItem("tabs-c")Third#end #end #@juiTabContentItem("tabs-a") tabs-a content #end #@juiTabContentItem("tabs-b") tabs-b content #end #@juiTabContentItem("tabs-c") tabs-c content #end#end |
通过上面的处理,封闭了代码的具体实现,而换之以容易理解的宏,在提升开发人员开发效率方面,提升代码的易维护性方面都有显著提升。尤其是在需要变化的时候,只要接口不变化,很多的时候,只要修改宏定义即可,对于程序员写的界面文件,完全可以做到透明化处理。 重构之后的结果
可以看到,重构之后的界面样式与原来没有任何变化。 接下来看看,JS的加载:从原来的许多个js文件,变成只加载两个,说明js文件已经被合并并压缩传输。
再来看看css的加载,可以看到,也是只需要一个就可以了:
重构之后写个小组件,是下面的样子:
1234567891011121314151617181920 | #@jarvisWidget("wid-id-0" '<strong>Default</strong> <i>Widget</i>') #@jarvisWidgetHeader() #end #@jarvisWidgetBody() #@widgetEditBox() <input class="form-control" type="text"> <span class="note"><i class="fa fa-check text-success"></i> Change title to update and save instantly!</span> #end #@widgetBody() <p> Widget comes with a default 10 padding to the body which can be removed by adding the class <code>.no-padding</code> to the <code>.widget-body</code> class. The default widget also comes with 5 widget buttons as displayed on top right corner of the widget header. </p> <a href="javascript:void(0);" class="btn btn-default btn-lg"> <strong>Big</strong> <i>Button</i> </a> #end #end#end |
总结 通过对SmartAdmin进行重构,成功的理清了smartadmin中的css,js关系,便于进行后续复用。 通过编写宏,可以在组件开发人员与页面开发人员之间进行隔离。由组件开发人员与js,css等打交道,而让页面开发人员只关注业务展现。