Tiny框架也不得不直視這個問題,確實來說,想解決這個問題,也是非常有難度與深度的,業界也有各種各樣的嘗試,這也是有各種各樣不同框架出現的原因。
Tiny框架構建者認為,完全采用壹種框架解決所有問題,是不現實的。而且即使目前找得到壹種非常好的框架,暫時可以滿足應用需要,但是隨著技術的發展,業務的進化,就會慢慢變得不再滿足業務需要。因此,Tiny框架構建從不再把做壹套UI組件去適各種需求作為自己的目標。
反過來,我們看看在做Web應用中,可能會碰到的問題:
UI中JS的引入與順序,JS合並的問題
UI中css的引入與順序,CSS合並的問題
UI中碰到性能問題時的影響範圍,比如:壹個樹出現問題,要改動許多用到樹的地方
代碼重復的問題,同樣的內容在許多地方都有,如果要改動就要改動許多個地方
整體布局調整困難的問題
程序員需要關註的內容太多的問題,JS,CSS,布局,後臺業務,前臺展現,尼瑪界面工程師必須得是全才才可以搞得定所有問題。
開發效率的問題
執行效率的問題,前臺響應要求速度更快
集群的問題
國際化的問題
...
因此,我在以前寫過壹篇文章:UI開發的終極解決方案感興趣的同學,可以去看看,今天的目標是利用TinyUI框架的重構SmartAdmin,使得更容易被使用。
SmartAdmin初識
SmartAdmin是壹套基於JQuery,Bootstrap構建的UI組件庫,說直白些,它就是個大雜燴,它把各種JQuery插件和Bootstrap整合到壹起,提供了壹整套基本完整的應用開發UI庫,基本是拿著它就可以用來非常專業的應用系統了。
下面是界面,當然它內嵌提供了四套皮膚,可以進行切換的:
由於SmartAdmin是商業產品,需要購買,因此不能提供其Copy,據說在Baidu可以搜到,據說可以下載。如果只是想看壹下的話,請點擊此鏈接:es with a default 10 padding to the body which can be removed by adding the class <code>.no-padding</code>?0?2
0?2to the <code>.widget-body</code> class. The default widget also comes with 5 widget buttons as displayed on top right?0?2 0?2corner of the widget header. </p> 0?2<a href="javascript:void(0);" class="btn btn-default btn-lg"> <strong>Big</strong> <i>Button</i> </a> 0?2?0?2 0?2</div> 0?2<!-- end widget content --> 0?2?0?2 0?2</div> 0?2<!-- end widget div --> 0?2?0?2</div>
這個程序員處理起來還是相當有難度的,好吧,這還不算過分的。
執行下面的命令:
dir *.js /s /w
運行結果:
1
2
所列文件總數:
0?2?0?2?0?2?0?2?0?2?0?2?0?2?0?2310 個文件?0?2?0?2?0?2?0?2?0?2 6,043,053 字節執行下面的命令:
dir *.css /s /w
運行結果:
1
2
所列文件總數:
0?2?0?2?0?2?0?2?0?2?0?2?0?2?0?2?0?236 個文件?0?2?0?2?0?2?0?2?0?2 1,511,412 字節裏面有這麽多的JS,有這麽多的CSS,它們的引入順序也是非常重要的,稍有差錯,就會有js錯誤的問題。
再來看看,JS加載過程:
可以看到,要訪問大量的js,CSS,對於服務器的壓力是比較大的,客戶端加載時間也是比較長的,程序員要厘清這些關系,也是非常困難的。
SmartAdmin重構
對SmartAdmin重構,是指按照Tiny框架的體系結構來進行重構。
第壹步,厘清關系
通過整理,發現smartadmin中使用的js插件有如下之多:
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
bootstrap
bootstrapProgressbar
bootstrapSlider
bootstrapTags
bootstrapTimepicker
bootstraptree
bootstrapWizard
ckeditor
colorhelpers
colorpicker
datatables
delete-table-row
dropzone
easyPieChart
excanvas
fastclick
flot
FontAwesome
fueluxwizard
fullcalendar
ie-placeholder
ion-slider
jquery
jquery-form
jquery-nestable
jquery-touch
jqueryui
jqueryvalidate
js-migrate
jstorage
knob
markdown
maskedInput
maxlength
morris
msieFix
multiselect
notification
noUiSlider
pace
prettify
raphael
select2
selectToUISlider
smartadmin
smartwidgets
sparkline
summernote
superbox
throttle-denounce
typeahead
vectormap
x-editable
第二步:UI插件,組件包化:
比如JQuery組件包化,就是編寫下面的文件:jquery.ui.xml
1
2
3
4
5
<ui-components>
0?2?0?2?0?2?0?2<ui-component name="jquery"> 0?2?0?2?0?2?0?2?0?2?0?2?0?2?0?2<js-resource>/jquery/jquery-1.11.0.js</js-resource> 0?2?0?2?0?2?0?2</ui-component></ui-components>
比如JQueryUI組修的包化,就是編寫下面的文件:jqueryui.ui.xml
1
2
3
4
5
6
<ui-components>
0?2?0?2?0?2?0?2<ui-component name="jqueryui" dependencies="jquery"> 0?2?0?2?0?2?0?2?0?2?0?2?0?2?0?2<js-resource>/jqueryui/js/jquery-ui-1.10.4.custom.js</js-resource> 0?2?0?2?0?2?0?2?0?2?0?2?0?2?0?2<css-resource>/jqueryui/css/smoothness/jquery-ui-1.10.4.custom.css</css-resource> 0?2?0?2?0?2?0?2</ui-component></ui-components>
比如BootStrap組件包化,就是寫下面的文件:bootstrap.ui.xml
1
2
3
4
5
6
<ui-components>
0?2?0?2?0?2?0?2<ui-component name="bootstrap" dependencies="jqueryui"> 0?2?0?2?0?2?0?2?0?2?0?2?0?2?0?2<css-resource>/bootstrap/css/bootstrap.min.css</css-resource> 0?2?0?2?0?2?0?2?0?2?0?2?0?2?0?2<js-resource>/bootstrap/js/bootstrap.js</js-resource> 0?2?0?2?0?2?0?2</ui-component></ui-components>
其它類推,最主要的目的就是要分清,用到哪些JS,哪些CSS,並且整理組件包之間的依賴關系,比如,上面BootStrap就依賴了jqueryui,當然jqueryui依賴了JQuery
通過上面的依賴樹Tiny框架就可以自動構建好CSS及JS資源。
因為這些資源都是放在Jar工程的main/resources目錄中,因此就直接打進jar包了。
第三步,編寫宏
比如,原來的Tab,需要涉及到html,js,編寫後續使用的宏如下:
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
#**
0?2* JqueryUI Tab 0?2* juiTab[1..1] 0?2*?0?2?0?2?0?2?0?2?0?2 juiTabHeader[1..1] 0?2*?0?2?0?2?0?2?0?2?0?2?0?2?0?2?0?2?0?2 juiTabHeaderItem[1..n] 0?2*?0?2?0?2?0?2?0?2?0?2 juiTabContentItem[1..n] 0?2*# 0?2#macro(juiTab $juiTabId)
<div id="$juiTabId">
$bodyContent
</div>
<script>
0?2?0?2?0?2?0?2$(document).ready(function(){ 0?2?0?2?0?2?0?2?0?2?0?2?0?2?0?2$('#$juiTabId').tabs(); 0?2?0?2?0?2?0?2});</script>
#end
0?2#macro(juiTabHeader)
<ul>
$bodyContent
</ul>
#end
0?2#macro(juiTabHeaderItem $juiTabContentItemId)
<li>
0?2?0?2?0?2?0?2<a href="#$juiTabContentItemId">$bodyContent</a></li>
#end
0?2#macro(juiTabContentItem $juiTabContentItemId)
<div id="$juiTabContentItemId">
$bodyContent
</div>
#end