一、引言

首先这些年关于前端技术层出不穷,从最早的只用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. Fragment在Activity中的应用 (转载)

    原文链接 http://www.cnblogs.com/nanxin/archive/2013/01/24/2875341.html 在本小节中介绍在Activity中创建Fragment. 官网有很 ...

  2. UCI

    数据库是加州大学欧文分校(UniversityofCaliforniaIrvine)提出的用于机器学习的数据库,这个数据库目前共有187个数据集,其数目还在不断增加,UCI数据集是一个常用的标准测试数 ...

  3. JS学习随手笔记

    ===================字符串===================== 字符串中间的空格也是要算长度的. 每一个字符都可以返回对应的Unicode 编码 文字的简单加密都是通过char ...

  4. GPRS优点介绍及GPRS上网相关知识(转)

    源:http://blog.chinaunix.net/uid-20745340-id-1878732.html 单片机微控制器以其体积小.功耗低.使用方便等特点,广泛应用于各种工业.民用的嵌入式系统 ...

  5. 强制修改mysql 中root的密码

    /etc/init.d/mysqld stop   (service mysqld stop )/usr/bin/mysqld_safe --skip-grant-tables另外开个SSH连接[ro ...

  6. webpack.config.js 参数简单了解

    webpack.config.js文件通常放在项目的根目录中,它本身也是一个标准的Commonjs规范的模块. var webpack = require('webpack'); module.exp ...

  7. 利用css3特性写出三角形(兼容IE浏览器)

    利用CSS写出三角形的效果 效果如图: 代码如下: .triangle-up { width:0px; height:0px; border-left:10px solid transparent; ...

  8. 利用rem实现webapp布局

    rem这是个低调的css单位,近一两年开始崭露头角,有许多同学对rem的评价不一,有的在尝试使用,有的在使用过程中遇到坑就弃用了. 但是我对rem综合评价是用来做web app它绝对是最合适的人选之一 ...

  9. PHP 正则小解

    正则表达式(Regular Expression) 正则表达式系统: 1.POSIX 2.Perl PHP中使用的regex是PCRE: NOTE:PCRE(Perl兼容正则表达式,Perl Comp ...

  10. MAC apache 2.4 启用目录访问

    1. 打开 httpd.conf 文件,在Options 后面添加 "Indexes",如下: <Directory "/Users/ChenShuo/Docume ...