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应该有以下特点:

  1. 代码可读性高,利于维护

  2. 强大的逻辑表现力

  3. 模块化,可以复用并整合各个模块

貌以目前还没有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控件的确是很好的方法,但我们更需要不依赖于后端语言的方案。


猫之良品
2.5k 声望139 粉丝

资深Drupal, magento与Joomla