1.前言
最近有人问我:你会前端开发吗? 我思索了一会儿,然后说:不会!于是,我被鄙视了!后来我看那些所谓会前端开发的人写的作品,我恍然大悟,原来会使用Html标签,会显示和隐藏Dom,会使用Ajax GET、POST就算懂得了前端开发。我想了下,或许我们对前端开发的定义并不明确。
2.前端是什么
前端是相对后端而说的,通俗地说就是直接与用户进行交互的,用户能够明确感知到的部分叫前端,不直接与用户交互,用户无法直接感知到的部分叫后端。(这个定义是我自己认为的)前端通常被通俗地称为UI,即用户接口(User Interface)。通常谈到前端,大家想到的是Html,CSS,Javascript等内容,更深入地则有UX(User Experience)的概念,强调如何让用户更便捷,更明确无误地做完操作。
3.前端开发应该考虑的问题
我个人并非从事前端开发的工程师,但自己一直在思考,前端究竟应该解决什么问题。我个人认为,前端解决的问题可以分为两方面:
1)与用户的交互相关的问题
用户交互的基本要求是准确无误,其次要求是快捷方便,最后要求是符合操作习惯。准确无误很好理解,即UI必须能够引导用户进行准确的操作,快捷方便就有点深入了。我们结合XP和Win7的开始菜单进行说明。
图 1 - xp 开始菜单
图 2 - Win 7 开始菜单
对比两个开始菜单就会发现,Win 7 的启动菜单自动列出常用的应用,而且支持搜索,而xp则需要通过三级鼠标导航才能找到最终的程序,这个操作是很高难度的,这就是方便快捷的体现。在UI设计中有一个基本原则就是认为用户是不可靠的,意思是用户随时有可能误操作,那么如何降低误操作引起的麻烦呢?答案就是尽量减少用户的操作。我们再对比下面两个例子。
图3 - xp 菜单
图 4 - win 7 菜单
我们对比图 3 和 图 4 发现,Win 7 菜单的误操作概率更低,为什么呢?因为选项本身就是一个链接,点击之后直接就下一步,而xp设计方案中,选择某个选项之后,再点击下一步,需要两个动作,少了一个操作,就少了一次误操作的可能!这些是UI设计必须关注的问题。
关于操作习惯,通常都是从上到下,从做到右,所以诞生了很多顶部导航菜单、左侧导航菜单等方案,甚至有二者合一的方案。但随着移动互联网的出现,有一种磁贴的设计方案出现了,因为这种对操作的要求更高,用户需要很简单的操作就干复杂的事情,比如打电话、导航等等。
图 5 - 企业应用风格
图 6 - 磁贴风格的菜单
众所周知,Win 8 的菜单主要是适应移动风格的,为了满足微软“移动优先”的战略要求。这就引出另一个话题:是否PC应用都能“移动”起来?现在我们当然知道这个答案是否定的,但是当年有多少人是生搬硬套,认为让移动设备访问web应用就是移动化,甚至云化。当然单纯从前端设计来说,考虑这个有点越俎代庖,但是“响应式”UI是必须要满足的,像Bootstrap这些响应式框架就是满足这类需求的,一套UI设计,满足PC设备、手机、平板的UI需求。
2)与应用的开发相关的问题
前端涉及到列表、表单等Dom元素,用户的操作通常会改变这些Dom的值,而某些Dom的值的改变会改变其他Dom的值,比如级联,甚至会改变UI,比如高级查询。这时候,UI和UI背后的数据之间存在的双向的关系。处理这种双向绑定的关系,不是一件简单的事情。那么有没有一个框架解决这个问题呢?我个人认为目前最优雅的解决方案就是Knockout,非常流行的MVVM框架。
我们来通过一个例子感受下MVVM!一个Table页面是这样的。
Javascript部分
var headers = [ { displayText: "Index", value: "id", width: "auto" }, { displayText: "Name", value: "name", width: "auto" }, { displayText: "Uri", value: "uri", width: "auto" }, { displayText: "Comment", value: "comment", width: "auto" }]; function TableViewModel(data){ var me = this; me.headers = ko.observableArray(headers); me.records = ko.observableArray(data); me.pagecount = ko.computed(function(){ if(me.records().length%pagesize == 0) return me.records().length/pagesize; else return me.records().length/pagesize + 1; }); me.count = ko.computed(function(){ return me.records().length; }); } $.ajax({ url: "/SpringDemo/home/user/data", type: "GET", success: function(data){ dataSource = data; tableViewModel = new TableViewModel(data.slice(0,pagesize)); ko.applyBindings(tableViewModel,$("#tab").get(0)); } });Html部分
<table id="tab" class="table table-striped table-bordered"> <caption>Visit Link List</caption> <thead> <tr class="success" data-bind="foreach:headers"> <th><a data-bind="text:displayText"></a></th> </tr> </thead> <tbody data-bind="foreach: records"> <tr> <td data-bind="text: id"></td> <td data-bind="text: name"></td> <td><a data-bind="attr: { href: '/SpringDemo' + uri}">Look</a></td> <td data-bind="text: comment"></td> </tr> </tbody> </table>得到的效果如下:
这里我们有分页的功能,当然也是通过Knockout实现的,但这并非今天讨论的重点,我们来看看数据的增加如何实现的。
save:function(record){ console.log(ko.toJSON(record)); var errCount = FormViewModel.errors().length; var data = {"name":record.name(),"uri":record.uri(),"comment":record.comment()}; //check exist var exist = false; if(errCount == 0 && exist){ $.ajax({ url:"/home/create", contentType:"application/json", //request format type:"POST", data: data, dataType:"text", //response format success:function(result){ //"SUCCESS" == result ? $("#myModal").modal("hide"):alert("save error"); tableViewMoel.records.push(data); } }); }else{ alert("please check your input,there were " + errCount + " errors."); } }这里如果单就前端操作来说,我们只是负责对Dom关联的数据进行操作,那么Knockout就帮助我们操作了Dom,这就是我们对MVVM的数据驱动的理解,另外,Dom也会带动数据的变化,如下图:
我们在表单中做了实时严重,这种验证我们并没有监听Dom的事件,而是注册了对数据的监听,这是如何做到的呢?
name : ko.observable().extend({ minLength: 3, maxLength: { params: 30, message: "名称最大长度为30个字符" }, required: { params: true, message: "请输入名称", } })我们仅仅注册对数据的侦听,但是Knockout就可以帮助我们完成剩下的事情,这样MVVM的双向绑定就体现得淋漓尽致了。
这还是不是最重要的一点,表单、表格等Dom背后的数据的加载,绑定都是Json格式的,表单的提交只需要把Json提交即可,这个过程非常简单:
ko.toJSON(record) 结果: {"name":"ss","uri":"ssd","comment":"fff","errors":["Please enter at least 3 characters."]}在上面的save中,我们知道这个record就是表单当前的状态的数据对象,这样方便了我们取值,转化等过程!
4.总结
什么是前端开发,我认为仅仅会使用Jquery,CSS,标签这些真的不太够,如何能构建复杂,稳定的前端架构才是灵魂,能够把握整体的风格,操作流程,习惯这些真的才是精髓,或许有一些是产品经理的事情。这仅仅是我个人偏颇的理解,欢迎交流!