一、引言

首先这些年关于前端技术层出不穷,从最早的只用js做简单验证,到现在发现好像大前端已经无所不能了的感觉。特别是为了降低前端开发复杂度,涌现了一大批 的MVC/MVVM模式的前端框架,不停了刷新我们的代码组织结构及开发模式,比如:BackboneJS、EmberJS、KnockoutJS、 AvalonJS(国产)、AngularJS、ReactJS等等。

二、现有主流框架

我们的开发模式第一次革命应该算是从google提出ajax一直到nodejs变化是非常的大,我们也在尝试着找到更合理更简单更适合的开发模式。我自 己也经历过从原生js的开发到使用jquery操作dom,再到应用knockoutjs、avalonjs、angularjs及reactjs到我们 的项目中(backbonejs、emberjs、polymer我没实际使用过),发现我们的程序越写越简单,而且越来越有意思。但每个框架专注点是不 一样的,而且也有一些缺点:
    1、angularjs,体积庞大过于复杂不适合轻量级应用,而且我对1.3放弃IE8及2.0的跳跃式发展耿耿于怀,最终开始把目光投向reactjs。
   
2、reactjs,研究了一段时间发现还真不错,首先是比较轻量极,性能也是很赞,最主要是它提出的Virtual
DOM的概念,我觉得也算是一个革新了,但是它其实算不上是一个框架,它的专注点在于生成UI,就跟ng中的directive一个等级的,所以很多东西
还要自己实现,它只能算我们的一个利器要架构一个复杂的应用还需要很多的工作。还有一点就是我比较不喜欢它的jsx这个玩意,虽然它可以在服务端处理。应
该算是我的个人偏见吧。
    3、polymer理念很超前,基于web component实现,我个人也觉得这是未来的趋势。
    但是目前来说对于Shadow DOM的浏览器的兼容性:http://caniuse.mojijs.com/Home/Html/item/key/shadowdom/index.html,我估计除了研究没人会想用它了,而且它还利用了html5的imports:http://www.html5rocks.com/en/tutorials/webcomponents/imports/,它这种模式产生的问题非常明显,就是需要import太多的html,而且还有嵌套的概念,可想而知。

三、对前端框架的想法

这些框架都很强悍,但是我觉得实际开发,一个适合好用的框架应该是要把已有的类库、插件等等的这些完美的结合起,并且提供简单易用的接口及合理的代码组织
结构,现有的jquery插件非常的多(其实jquery比这些东西流行的多的多),现有的开源很多的类库我们都可以使用。我的思路是现有的这些资源应该
要充分利用起来。所以我想自己整一个框架出来。我构想设计了下:

1、web component思路,结合Shadow DOM 及 Virtual DOM,如果支持Shadom DOM就使用Shadom DOM否则使用Virtual DOM实现。
2、控件定义尽量简单易懂,可快速包装现有的插件,控件存在继承的概念,控件存在少量修改时可以考虑继承覆写的方式实现。
3、实现MVVM的双向绑定,实际是三向(实际dom,控件实例(无论是shadow还是virtual都对应到一个virtual dom)、数据)

我暂时把这个项目叫做 Chitu.js 即赤兔.js,接下来会放到github上。

四、细化及实现思路

1、标签定义
比如我们需要一个hello的控件

<hello id="id1" binding="hello1"></hello>

2、控件定义
我们定义hello的控件

chitu.component('hello', function (self) {
//属性定义
self.name = {
get: function () { return self.root.getAttribute("name"); },
set: function (value) { self.root.setAttribute("name", value); }
};
self.value = {
get: function () { return self.root.innerText; },
set: function (value) { self.root.innerText = value; }
}; //... //事件定义
self.onclick = function(){ }; //... //方法定义
self.setColor = function(color){
self.root.style.color = color;
}; //... //控件生成
self.render = function () {
//...
var text = document.createTextNode(self.value);
return text;
}; //控件消亡
self.dispose = function(){ };
});

这里就是整个hello的控件的定义,就是把hello控件实例看作一个virtual节点,这是reactjs的思路,但是实现上面如果是支持shadow dom可以使用把render中返回的节点放到shadow dom中。

这里的控件属性与实际dom的双向连动是通过引入get set方法来实现的,实际上这个代码还需要经过一次complie处理,把get set方法通过ES5的Object.defineProperty方法转换成属性(先不考虑兼容性)。

这里如果要集成jquery控件就非常容易了,比如combobox控件:

chitu.component('combobox', function(self){
self.value = {
get:function(){return $(root).combobox('getValue');},
set:function(value){$(root).combobox('setValue',value);}
}; self.render = function(){
$(root).combobox(options);
return root;
}; self.dispose = function(){
$(root).combobox('dispose');
};
});

如果控件需要继承可以这样,定义一个mygridEx继承mygrid控件

chitu.component('mygridEx', function(self){
//覆写属性
self.attr1 = {
get:function(){},
set:function(){}
}; //覆写方法
self.getRowCount = function(){ }
},'mygrid');

3、控制器

chitu.controller('ctrl1',function(scope){
scope.data ={
tenant_id:'001',
tenant_name:'tenantname',
height:100
}; scope.hello={
name:'helloname',
value:'world'
} scope.grid1 ={
width:500,
height:'{data.height}',
rowClick:function(row){
scope.vdom.id1.value = row.name;
}
}; scope.search1={
text:'{data.teannt_name}',
searchClick:function(){ }
};
});

这里需要解释下<hello id="id1" binding="hello1"></hello>

这里的binding实际上对应的是controller当中的属性,这个属性其实就是控件的选项参数,我们以前调用jquery控件时

$('#id').jqgrid({
//一堆参数
});

这样的话,这一堆参数就可以通过一个binding跟页面联系起来,方便控件的使用,当然还可以在控件定义时就定义好很多默认的参数,只需要传入需要改变的参数。
当然我们的参数也不一定都要写在binding当中,也可以单独绑定控件属性

<hello id="id1"  [value]="world" ></hello>
<hello id="id1" [value]="{data.tenant_name}" ></hello>
<hello id="id1" binding="hello1" [value]="world" [onclick]="search1.searchClick"></hello>

第一行:没有对应的binding属性,只有一个value属性,value的值为world
第二行:value的值双向绑定到controller中的data.tenant_name数据上

第三行:先从bindig的hello1中取值,如果有[value]则覆盖原值

这里为什么给属性加上[中括号],是因为属性叫什么名字都可能,尽量避免和原dom属性冲突。

控件器中还有一点设计值得说的是,我们可以把数据集中在scope.data中

1、其它地方绑定只需要{data.row1.field1}这样指定绑定就好

2、我们可以不需要先data中的结构是怎么样子,根据绑定关系生成data的结构

3、大多数情况下我们取回来的数据就是一个返回result,我们直接赋值给scope.data即可,不需要hello1.value = result.name , grid1.data = result.list;这样的处理。

4、我们需要提交数据时,也只需要从data中取即可,非常方便

当然对于普通的标签,我们也是可以绑定的

<div [title]="{data.title}" [text]="{data.text}" [onclick]="search1.searchClick" ></div>

这样一来,我们的代码可能就会集中在controller的一些方法当前中了,我们在controller中可以直接获取到每个控件实例,可以直接访问控件的各个属性即可实现交互。

当然如果有绑定到data数据中,直接操作数据也可以实现ui交互了。

五、关于可能存在的问题和探索

上面我给大家描述了我的思路及想法,我们再分析可能面对的问题。
1、兼容性

目前只是在尝试阶段,很多问题还没碰到,我的目标是尽量做到IE8+

2、性能

关于性能的消耗,可能主要是在于节点扫描、控件render、属性绑定及属性频繁的刷新。节点扫描当然会有些消耗,但是它带来的方便性可以忽略它的消耗,
除非你想一个一个控件指定去手动调用,控件render就取决了你写的控件本身了,不算是这个框架的问题,属性绑定在数据量没有大到一定程度是基本是不会
有问题的。

3、开发效率

开发效率主要就取决于是否做到了关注点分离,代码组织是否清晰合理简单易懂,代码只需要写有变化的东西,把重复的细节都封装起来,这个只能是尽量做到了。

关于我的其它的一些想法

1、需不需要引入类似css的东西用于分离页面与controller之间的绑定,这样还可以去除节点扫描,提高性能,如下

var binding={
'#id':'todo1',
'#grid1':'grid',
'#hello1':'hello'
};

2、关于render处理 
    a、用代码实现(原生、jquery)

b、模板实现或拼接字符串

c、通过预生成的方式(类似jsx,也可通过nodejs c# java等语言)

3、关于属性刷新

    因为控件属性是直接绑定到原生的dom上的,如果出现了大量的属性刷新恐带来性能问题,是否考虑一个参数用来开启关闭(立即刷新、一次性刷新)

4、跟amd cmd结合

    这个是没有任何问题的,而且如果控件都是包装第三方控件的话,实现动态加载还可以更加的方便。

5、是否还需要引入其它特性,如ng注入特性、过滤器等

6、哪些环节还可以在服务端预处理

六、结束语

目前只是把我的想法记录起来,有很多问题可能还没具体想清楚,现在自己先实现了一个简易的版本,等我先折腾出一个0.1的版本放到github上,如果有兴趣的朋友,可以加入一起设计构思及开发。大家有好的想法,意见建议欢迎给我留言

关于自己封装Web前端框架的思考和探索的更多相关文章

  1. Web前端框架与类库

    Web前端框架与类库的思考 说起前端框架,我也是醉了.现在去面试或者和同行聊天,动不动就这个框架碉堡了,那个框架好犀利. 当然不是贬低框架,只是有一种杀鸡焉用牛刀的感觉.网站技术是为业务而存在的,除此 ...

  2. React 还是 Vue: 你应该选择哪一个Web前端框架?

    学还是要学的,用的多了,也就有更多的认识了,开发中遇到选择的时候也就简单起来了. 本文作者也做了总结: 如果你喜欢用(或希望能够用)模板搭建应用,请使用Vue    如果你喜欢简单和“能用就行”的东西 ...

  3. Web前端框架学习成本比较及学习方法

    就项目中自己用过的前端框架的学习成本比较与学习心得分享 刚工作时间不长只用过这几个框架下面是难易程度比较: 不论哪个web前端框架, 究其本质都是把页面的数据传递给后台服务器语言(如java)进行处理 ...

  4. 国内5款优秀的WEB前端框架

    1. JX(腾讯) 官网地址:http://alloyteam.github.io/JX/#home JX 是一个类似 Google Closure Library 的 Web 前端开发框架,服务于 ...

  5. Web前端框架与移动应用开发第八章

    Web前端框架与移动应用开发:制作58招聘专题页 1.html代码: <!DOCTYPE html><html><head> <meta charset=&q ...

  6. Web前端框架与类库的思考

    说起前端框架,我也是醉了.现在去面试或者和同行聊天,动不动就这个框架碉堡了,那个框架好犀利. 当然不是贬低框架,只是有一种杀鸡焉用牛刀的感觉.网站技术是为业务而存在的,除此毫无意义,框架也是一样.在技 ...

  7. Web前端框架与类库的思考【转】

    前端框架的理解误区 网站的价值在于它能为用户提供什么价值,在于网站能做什么,而不在于它是怎么做的,所以在网站还很小的时候就去追求网站的架构框架是舍本逐末,得不偿失的.前端框架同理,如果是一个简单的页面 ...

  8. Web前端框架汇总

    在做web开发的时候难免遇到一个问题,那就是,选择什么样的框架.下面把前端的框架简单的列一下. 1.flex Apache基金会今天发布了Flex 4.8版本,这是Adobe将Flex捐献给Apach ...

  9. JavaScript前端框架的思考

    (此文章同时发表在本人微信公众号"dotNET每日精华文章",欢迎右边二维码来关注.) 题记:现在JavaScript前端框架层出不穷,尤其Angular进入到2.x时候之后,我们 ...

随机推荐

  1. 破解JS加密:url unicode加密而已

    加密所在的地方:http://tool.chinaz.com/Tools/UrlCrypt.aspx?url=www.baidu.com 结果: http://%77%77%77%2E%62%61%6 ...

  2. c#中控制不能从一个case标签贯穿到另一个case标签

    每个非空的case标签都得以break结束,肯定是两个case之间少了一个break了

  3. Base64编码Java实现

    一.什么是Base64编码 Base64是网络上最常见的用于传输8Bit字节代码的编码方式之一.Base64 主要不是加密,它主要的用途是把一些二进制数转成普通字符用于网络传输. 由于一些二进制字符在 ...

  4. Moocryption

    Moocryption 题目描述 Unbeknownst to many, cows are quite fond of puzzles, particularly word puzzles. Far ...

  5. JQuery实现两侧浮动广告

    1.描述 两侧浮动显示广告 2.要点 其实就是一直在变浮动广告距顶部的值. 3.代码 <!DOCTYPE html> <html> <head> <meta ...

  6. Ubuntu Server PHP常用扩展库的安装

    sudo apt-get install php5-gd curl libcurl3 libcurl3-dev php5-curl

  7. 关于iOS性能调优

    性能调优一直都是作为高阶iOS开发者的一个入门门槛,下面我搜集了日常查阅资料中见到的各种高质量调优博文,仅供参考 UIKit性能调优实战讲解 iOS 高效添加圆角效果实战讲解

  8. (一)phoneGap之环境搭建教程及其example分析

    phoneGap之环境搭建教程及其example分析 一.环境搭建 与普通的开发android应用一样,phoneGap也同于原生android应用一样,环境相同,只是有部分不同,下面就我做理解,进行 ...

  9. mysql、mysqli、pdo使用

    一.php手册关于MySQL的说明:    This extension is not recommended for writing new code. Instead, either themys ...

  10. iOS ZBar扫码简单实现

    导入ZBarSDK文件并引入一下框架 AVFoundation.framework CoreMedia.framework CoreVideo.framework QuartzCore.framewo ...