HTML与CSS已经可以表现任何的用户界面,CSS3甚至可以表现动作,但仍需要动态交互性,这都需要javascript来弥补,HTML, CSS, Javascript就构成了WEB UI,缺一不可。但HTML与Javascript这两种差异十分大的语言在混合成UI却并不容易,这是因为javascript本来就不适合与HTML混合使用,但到了现在javascript已经是前端的主流,有着不可动摇的地位,所以如果更合理地把这三种元素整合成了前端工程师头痛的问题。
WEB技术已经发展二十多年的今天,又有那些解决方案呢?我先说一说我接触过的方案。
jQuery
jQuery是大流行,绝大部分WEB控件都基于它,WEB UI离不开它。但jQuery更多被视为工具库,而不是一套UI,它没有一套UI的开发规范,各式各样的UI有各种使用方法,让人不得不查询文档,而很多UI控件之间难以交互,可能需要写一大堆callback实现交互。以jQuery UI为例,经典代码如下:
<div id="tabs">
<ul>...</ul>
<div id="tab1">...</div>
</div>
<script>
$(function() {
$( "#tabs" ).tabs();
});
</script>
jQuery UI代表着大多数jQuery插件的使用方法,可以看得出代码也相当的简洁,只要有固定的HTML结构与一个触发源基本就成了。不过这仅仅只是表现一种效果,互动性比较弱。例如它现在需要CLICK TAB或者HOVER可以进行元素切换,我想其它插件自动激活它的切换就需要写callback,有些效果默认没有,我需要扩展新的效果,需要写不少javascript代码。
extjs
这是一套很专业很庞大的UI,完全由javascript来构造UI,省去了HTML和CSS,让UI的语种更统一。javascript逻辑性很强,所以更为复杂的互动性可以更容易被实现。但完全由javascript构造,代码难以有可读性,而且难以掌握。HTML其实都是很好的结构表现语言,但extjs直接把它们放弃了,就去掉了代码表现力的优势。
Ext.onReady(function () {
//创建一个窗体
var win = new Ext.Window({
width: 300,
height:300,
items: [],
modal: true,
buttonAlign: 'center',
buttons: [{
text: '测试', id: 'btnTest', handler: function () {
Ext.Msg.show({
title: '询问',
msg: '您喜欢 ExtJs 吗?',
fn: processResult,
icon: Ext.Msg.QUESTION,
buttons: Ext.Msg.YESNO
});
}
}
]
});
win.show();
});
AngularJS
无疑是MVVM的代表作,其最大优点是大量使用了HTML的构造方法并弥补HTML的互动需要,让代码变得更为优雅。使用它来构造富客户端很适合,不过组件概念比较弱,代码复用性不高,组件一般用jquery等工具来构造,不过这也并无不好,只是某些情况下仍不够理想。
<body ng-controller="PhoneListCtrl">
<ul>
<li ng-repeat="phone in phones">
{{phone.name}}
<p>{{phone.snippet}}</p>
</li>
</ul>
</body>
React
与一般的MVVM不同,也与extjs不同,它主要是以javascript为主,但它没有抛弃HTML的优势,让HTML在javascript中更自然,创造了JSX的语法。虽然语法看起来比较奇怪,但我认为这是目前各取所长的最好的方案,然而React目前还不够好,它有很多改进的空间,但JSX的路是对的。
var ListItemWrapper = React.createClass({
render: function() {
return <li>{this.props.data.text}</li>;
}
});
var MyComponent = React.createClass({
render: function() {
return (
<ul>
{this.props.results.map(function(result) {
return <ListItemWrapper key={result.id} data={result}/>;
})}
</ul>
);
}
});
理想结构
综合以上架构,我认为UI应该有以下特点:
代码可读性高,利于维护
强大的逻辑表现力
模块化,可以复用并整合各个模块
貌以目前还没有UI可以完全实现这些特点,不过不妨以JSX的方案假设一下,我希望有一个UI可以让我这样写代码:
<products>
<products_filter type="type1"/>
<products_list type="type1" data="{{products}}">
<div class="row">
<label>{{attr.name}}</label>
<div>{{attr.price}}</div>
</div>
</products_list>
</products>
<script type="text/jsx">
app.addModule('products_filter', function() {
app.render(
<form>
<input name="keywords" type="text"/>
<button>submit</button>
</form>
);
});
app.addModule('products_list', function(element) {
var data = element.getAttribute('data');
var row = element.getBody();
app.render(
<ul>
{data.map(function(result) {
return <li><row name="{result.name}" price="{result.price}" /></li>;
})}
</ul>
);
});
</script>
这样看起来有就像ASP.NET的控件,ASP.NET控件的确是很好的方法,但我们更需要不依赖于后端语言的方案。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。