传送门

observejs:https://github.com/kmdjs/observejs

本文演示:http://kmdjs.github.io/observejs/list/

本文代码:https://github.com/kmdjs/observejs/tree/master/example/list

写在前面

javascript的编程体验一直被改善,从未停止过。从最早的Jscex(现在的windjs),改善异步编程体验。如今ES6的Generator改善异步编程体验。还有类似的seajs、requirejs提供极致的模块化开发体验;五花八门的Class.js改善面向对象编程体验;kmdjs同时改善模块化编程、面向对象编程和构建体验;各式各样的template.js改善数据->标记的体验。

所有的改善,使代码更直观、友好,使程序易维护、可扩展。

最近使用observejs开发组件,发现有几大优点:

  • Dom操作几乎绝迹
  • 专注于数据操作
  • 视图全自动更新
  • 性能棒棒的
  • 仅一行代码搞定上面四点

本文使用世界上最简单的List组件作为例子,大家通过该例子感受一下observejs组件开发改善之处。

组件代码

var List = function (option) {
this.option = option;
this.data = option.data;
this.parent = document.querySelector(this.option.renderTo);
this.tpl =
'<div class="list-group" style=" text-align: center;width:<%=typeof width === "number"?width+"px":width%>;" >'
+ ' <% for ( var i = 0, len = data.length; i < len; i++) { %>'
+ '<% var item = data[i]; %>'
+ '<a class="list-group-item <%=item.active ? "active" : ""%> <%=item.disabled ? "disabled" : ""%>" href="<%=item.href%>" target="<%=item.target?item.target:""%>"><%=item.text%><\/a>'
+ '<% } %>'
+ '<\/div>';
this.render();
//list.render建议使用debounce来控制执行频率提高性能,或者和react一样在下次执行requestAnimFrame的时候更新
observe(this, "option", this._debounce(this.render, 200));
}
List.prototype = {
render: function () {
if (this.node) this.parent.removeChild(this.node);
this.parent.innerHTML += this._tpl(this.tpl, this.option);
this.node = this.parent.lastChild;
},
clear:function(){
this.data.size(0);
},
remove:function(index){
this.data.splice(index,1);
},
add:function(item){
this.data.push(item);
},
edit:function(index,item){
this.data[index]=item;
},
disable:function(index){
this.data[index].disabled = true;
},
_tpl: function (str, data) {
var tmpl = 'var __p=[];' + 'with(obj||{}){__p.push(\'' +
str.replace(/\\/g, '\\\\')
.replace(/'/g, '\\\'')
.replace(/<%=([\s\S]+?)%>/g, function (match, code) {
return '\',' + code.replace(/\\'/, '\'') + ',\'';
})
.replace(/<%([\s\S]+?)%>/g, function (match, code) {
return '\');' + code.replace(/\\'/, '\'')
.replace(/[\r\n\t]/g, ' ') + '__p.push(\'';
})
.replace(/\r/g, '\\r')
.replace(/\n/g, '\\n')
.replace(/\t/g, '\\t') +
'\');}return __p.join("");', func = new Function('obj', tmpl); return data ? func(data) : func;
},
_debounce: function (func, wait, immediate) {
var timeout;
return function () {
var context = this, args = arguments;
var later = function () {
timeout = null;
if (!immediate) func.apply(context, args);
};
var callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(context, args);
};
},
}

ps:模版引擎来自GMU,当然你可以使用任何你喜欢的额模版引擎

组件使用

var list = new List({
data: [
{ text: "天下太贰", disabled: true, active: true },
{ text: "魔兽争霸", href: "##", target: "_blank" },
{ text: "魔兽世界" },
{ text: "坦克世界" },
{ text: "超级玛丽", disabled: true }
],
width: 150,
renderTo: "body"
})
list.edit(1,{text:"haha"})
list.add({ text: "aaaa" });
list.remove(2, 1);
list.disable(2);
list.remove(1);
//操作数据等于操作dom
list.data[0].text="aaaaaaa";

组件分析

其中仅需要一行

observe(this, "option", this._debounce(this.render, 100));

就可以实现option的监听,option包含组件的配置,以及数据,数据的变换都能够通知render方法的调用。

可以看到render方法摧毁了整个dom,然后根据数据重新渲染dom。所以控制render的执行频率变得尤其重要。

如果数据变化频繁,render方法调用频繁,从而降低性能,所以,可以看到上面使用debounce控制render执行的频率。

如果不使用debounce,也有第二种方案控制render频率。该方案和react一样,在requestAnimateFrame下次循环的时候去check组件是否要re-render,需要的话就重新渲染。如果一个页面有一百个组件,都统一在requestAnimateFrame循环中check是否re-render。

可以看到,只有render方法里有dom操作。clear、remove、add、edit、disable都只关心数据,数据变了自动会通知到render。

改善的地方在哪里?分两处地方:

1.组件内部代码,内部的增删改查都只关注数据就行

2.组件使用代码,操作数据等同于操作dom

当然如果不使用赋值又没有observejs的情况下可以使用方法调用的方式,使得一行代码什么都能干,但是如果属性太多,你得定义非常多setXXX方法。但你必须知道:赋值胜于method(即【obj.name=xx】>【obj.setName(xx)】)、约定胜于配置:)。

如果你不是很适应react激进虚拟dom和jsx,如果你反感react放弃了HTML+CSS大量优秀特性功能,如果以后dom性能好了,全世界都i78核+ssd了,那么HTML+CSS才是王道啊。

observejs也许是你的另一选择,欢迎尝试,感谢对observejs提出那么多宝贵建议和意见的童鞋。

observejs:https://github.com/kmdjs/observejs

本文演示:http://kmdjs.github.io/observejs/list/

本文代码:https://github.com/kmdjs/observejs/tree/master/example/list

observejs改善组件编程体验的更多相关文章

  1. 基于 OSGi 的面向服务的组件编程,helloworld

    基于 OSGi 的面向服务的组件编程 OSGi(Open Services Gateway Initiative,开放服务网关协议)提供了一个面向服务组件的编程模型,基于 OSGi 编程,具有模块化, ...

  2. 基于 OSGi 的面向服务的组件编程

    作者:曹 羽中 (caoyuz@cn.ibm.com), 软件工程师, IBM中国开发中心 出处:http://www.ibm.com/developerworks/cn/opensource/os- ...

  3. 全新升级的AOP框架Dora.Interception[1]: 编程体验

    多年之前利用IL Emit写了一个名为Dora.Interception(github地址,觉得不错不妨给一颗星)的AOP框架.前几天利用Roslyn的Source Generator对自己为公司写的 ...

  4. kmdjs集成uglifyjs2打造极致的编程体验

    回顾 上篇文章大概展示了kmdjs0.1.x时期的编程范式: 如下面所示,可以直接依赖注入到function里, kmdjs.define('main',['util.bom','app.Ball', ...

  5. Atitit 面向对象编程(OOP)、面向组件编程(COP)、面向方面编程(AOP)和面向服务编程(SOP)的区别和联系

    Atitit 面向对象编程(OOP).面向组件编程(COP).面向方面编程(AOP)和面向服务编程(SOP)的区别和联系 1. 面向组件编程(COP) 所以,组件比起对象来的进步就在于通用的规范的引入 ...

  6. vue.js2.0 自定义组件初体验

    理解 组件(Component)是 Vue.js 最强大的功能之一.组件可以扩展 HTML 元素,封装可重用的代码.在较高层面上,组件是自定义元素, Vue.js 的编译器为它添加特殊功能.在有些情况 ...

  7. DSAPI多功能组件编程应用-HTTP监听服务端与客户端_指令版

    前面介绍了DSAPI多功能组件编程应用-HTTP监听服务端与客户端的内容,这里介绍一个适用于更高效更快速的基于HTTP监听的服务端.客户端. 在本篇,你将见到前所未有的超简化超傻瓜式的HTTP监听服务 ...

  8. Dora.Interception,为.NET Core度身打造的AOP框架 [1]:更加简练的编程体验

    很久之前开发了一个名为Dora.Interception的开源AOP框架(github地址:https://github.com/jiangjinnan/Dora,如果你觉得这个这框架还有那么一点价值 ...

  9. 依赖注入[6]: .NET Core DI框架[编程体验]

    毫不夸张地说,整个ASP.NET Core框架是建立在一个依赖注入框架之上的,它在应用启动时构建请求处理管道过程中,以及利用该管道处理每个请求过程中使用到的服务对象均来源于DI容器.该DI容器不仅为A ...

随机推荐

  1. SQLServer 各版本区别

    SQLServer 2012 新特性 通过AlwaysOn实现各种高可用级别 通过列存储索引技术实现超快速的查询,其中星型链接查询及相似查询的性能提升幅度可高达100倍,同时支持超快速的全文查询 通过 ...

  2. IIS启动失败,启动Windows Process Activation Service时,出现错误13:数据无效 ;HTTP 错误 401.2 - Unauthorized 由于身份验证头无效,您无权查看此页

    因为修改过管理员账号的密码后重启服务器导致IIS无法启动,出现已下异常 1.解决:"启动Windows Process Activation Service时,出现错误13:数据无效&quo ...

  3. CentOS:ECDSA host key "ip地址" for has changed and you have requested strict checking(转)

    原文地址:http://blog.csdn.net/ausboyue/article/details/52775281 Linux SSH命令错误:ECDSA host key "ip地址& ...

  4. POJ1743 Musical Theme [后缀数组]

    Musical Theme Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 27539   Accepted: 9290 De ...

  5. 递归实现n(经典的8皇后问题)皇后的问题

    问题描述:八皇后问题是一个以国际象棋为背景的问题:如何能够在8×8的国际象棋棋盘上放置八个皇后, 使得任何一个皇后都无法直接吃掉其他的皇后?为了达到此目的,任两个皇后都不能处于同一条横行.纵行或斜线上 ...

  6. 【腾讯Bugly干货分享】彻底弄懂 Http 缓存机制 - 基于缓存策略三要素分解法

    本文来自于腾讯Bugly公众号(weixinBugly),未经作者同意,请勿转载,原文地址:https://mp.weixin.qq.com/s/qOMO0LIdA47j3RjhbCWUEQ 作者:李 ...

  7. web音乐播放器总结

    前言 项目暂时告一段落,胸中有股炽热之气望喷涌而出!忍不住吐槽,为什么程序员要加班啊,为什么产品下达deadline,就得把这生死剑架在程序员的脖子上.卧槽,听说程序员在国外是叫工程师的.最近看了很多 ...

  8. 【Java并发编程实战】-----“J.U.C”:ReentrantReadWriteLock

    ReentrantLock实现了标准的互斥操作,也就是说在某一时刻只有有一个线程持有锁.ReentrantLock采用这种独占的保守锁直接,在一定程度上减低了吞吐量.在这种情况下任何的"读/ ...

  9. git 常见命令解析

    转载自http://www.rainkong.net/post/git-image.html 之前用的都是svn ,git还是要了解的,万一哪天要用了呢

  10. Docker之Compose服务编排

    Compose是Docker的服务编排工具,主要用来构建基于Docker的复杂应用,Compose 通过一个配置文件来管理多个Docker容器,非常适合组合使用多个容器进行开发的场景. 说明:Comp ...