基于Nuclear的Web组件-Todo的十一种写法

刀耕火种

刀耕火种是新石器时代残留的农业经营体式格局。又称迁徙农业,为原始生荒垦植制。
var TodoApp = Nuclear.create({
    add: function (evt) {
        evt.preventDefault();
        var textBox = this.node.querySelector('input');
        this.option.items.push(textBox.value);
    },
    installed: function () {
        var form = this.node.querySelector('form');
        form.addEventListener('submit', this.add.bind(this), false);
    },
    render: function () {
        return '<div>\
                 <h3>TODO</h3>\
                 <ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>\
                  <form >\
                   <input type="text"  />\
                   <button>Add #{{items.length}}</button>\
                 </form>\
                </div>';
    }
});

new TodoApp( { items: [] },"#container");

这类誊写体式格局依靠连续了jQuery时代的头脑体式格局:

  • js里查找dom

  • js里绑定事宜

在之前的文章里写过,假如不运用组件化编程,js里查找dom以及在js里绑定事宜可能会带来以下题目:

  • 糟蹋带宽

  • 用户反应无相应

  • 剧本毛病

  • 页面短暂紊乱

上面的誊写体式格局粗犷、原始、落伍,即:刀耕火种。

石器锄耕

“石器锄耕”是奴隶社会时代的重要垦植体式格局,这一时代农业已经有了很大的生长。
var TodoApp = Nuclear.create({
    onRefresh: function () {   
        this.form.addEventListener("submit", function (evt) {
            evt.preventDefault();                
            this.option.items.push(this.textBox.value);
        }.bind(this), false);
    },
    render: function () {
       return '<div>\
                 <h3>TODO</h3>\
                 <ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>\
                 <form nc-id="form" >\
                   <input nc-id="textBox" type="text"  />\
                   <button>Add #{{items.length}}</button>\
                 </form>\
               </div>';
    }
},{
    diff:false
});

new TodoApp( { items: [] },"#container");

会发明,查找dom的代码已销声匿迹。直接标记nc-id,就自动挂载在this下。
值得注意的是,传入了第二参数封闭了DOM diff。关掉diff的效果就是,每次组件HTML会悉数从新替代衬着,绑定的事宜悉数丧失,所以须要将绑定事宜的代码写入onRefresh里,如许每次从新衬着都邑再绑定一次。
比刀耕火种先进一点:石器锄耕。

犁庭扫穴

黄龙:即黄龙府,辖地在今吉林一带,应该是指长春市农安县,为金人要地。一向打到黄龙府。指摧毁仇人的巢穴。指杀敌取胜。
var TodoApp = Nuclear.create({
    add: function (evt) {   
            evt.preventDefault();                
            this.option.items.push(this.textBox.value);
    },
    render: function () {
       return '<div>\
                 <h3>TODO</h3>\
                 <ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>\
                 <form onsubmit="add(event)" >\
                   <input nc-id="textBox" type="text"  />\
                   <button>Add #{{items.length}}</button>\
                </form>\
               </div>';
    }
});

new TodoApp( { items: [] },"#container");

会发明,查找dom和绑定的代码同时销声匿迹!!

  • 须要运用input,直接标记nc-id为textBox,就能够this.textBox接见

  • 须要绑定事宜,直接在HTML内声明事宜和回调onsubmit=”add(event)”

也能够经由过程add(event,this)拿到event和触发该事宜的dom元素。

代码浅显简约清洁直接,目标直观邃晓。故:犁庭扫穴。

子承父业

宋·释道原《景德传灯录·利山和尚》:“僧问:不历僧只获法身,请师直指。师云:子承父业。”
var TodoList = Nuclear.create({
    render: function () {
        return '<ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>';
    }
});

var TodoApp = TodoList.create({
    add: function (evt) {
        evt.preventDefault();
        this.option.items.push(this.textBox.value);
    },
    render: function () {
        return '<div>\
                 <h3>TODO</h3>'
                + this._super.render() +
                '<form  onsubmit="add(event)" >\
                   <input nc-id="textBox" type="text"  />\
                   <button>Add #{{items.length}}</button>\
                 </form>\
               </div>';
    }
});

new TodoApp({ items: [] },"#container");

TodoApp不过是TodoList的炎黄子孙,故TodoApp能够经由过程this._super接见父辈。也可接见父辈任何要领。有人会说:“组合”优于“继续”的。一定要邃晓:OOP既能组合也能继续,是不争执的。且看下面例子。

万夫一力

明·刘基 《郁离子·省敌》:“万夫一力,天下无敌。”
var TodoList = Nuclear.create({
    render: function () {
        return '<ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>';
    }
});

var TodoApp = Nuclear.create({
    install: function () {
        this.todoList = new TodoList({ items: [] })
    },
    add: function (evt) {
            evt.preventDefault();
            this.todoList.option.items.push(this.textBox.value);
            this.refresh();
    },
    render: function () {
       return '<div>\
                 <h3>TODO</h3>'
                 + this.todoList.render()+
                 '<form onsubmit="add(event)" >\
                   <input nc-id="textBox" type="text"  />\
                   <button>Add #'+this.todoList.option.items.length+'</button>\
                 </form>\
               </div>';
    }
});

new TodoApp( {},"#todo2Container");

前一个例子的继续,这个例子是组合。不能说你的框架是Class base就不能运用组合,这是天大的误会。而我依稀记得极限编程关于面向对象设想的推论是:优先运用对象组合,而不是类继续。作为框架的设想者,虽然会有一些束缚,然则假如连组合和继续都不能共存,那就是设想的最大败笔。
运用Nuclear既能继续也能组合,症结看程序逻辑该怎样笼统和完成复杂度。

一刀两断

唐·孟郊《去妇》诗:“妾心藕中丝;虽断犹连累。”
var TodoList = Nuclear.create({
    render: function () {
        return '<ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>';
    }
});

var TodoApp = Nuclear.create({
    install: function () {
        this.todoList = new TodoList(this.option)
    },
    add: function (evt) {
            evt.preventDefault();                
            this.option.items.push(this.textBox.value);
    },
    render: function () {
       return '<div>\
                 <h3>TODO</h3>'
                 + this.todoList.render()+
                 '<form  onsubmit="add(event)"  >\
                   <input nc-id="textBox" type="text"  />\
                   <button>Add #{{items.length}}</button>\
                 </form>\
               </div>';
    }
});

new TodoApp( { items: [] },"#container");

这个例子和上个例子的区别是:共用option。option的变更会自动更新依靠option的组件。

到处为家

 《汉书·高帝记》:“且夫皇帝以到处为家。”
var TodoApp = Nuclear.create({
add: function (evt) {   
        evt.preventDefault();                
        this.option.items.push(this.textBox.value);
},
render: function () {
   return '<div>\
             <h3>TODO</h3>\
             <ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>\
             <form onsubmit="add(event)" >\
               <input nc-id="textBox" type="text"  />\
               <button>Add #{{items.length}}</button>\
             </form>\
           </div>';
}
});
var todo= new TodoApp( { items: [] });

todo.setNuclearContainer('#container');

且看上面的new TopApp没传第二个参数指定容器。背面运用setNuclearContainer指定容器。这个场景照样比较罕见,建立游离态组件,后续根据须要指定容器。AlloyLever就是这么干的: https://github.com/AlloyTeam/AlloyLever/blob/master/src/js/main.js

为虎傅翼

三国·蜀·诸葛亮《心书·兵机》:“将能执兵之权,操兵之势,而临群下,臂如猛虎加上羽翼,而飞翔四海。”
var TodoApp = Nuclear.create({
    add: function (evt) {
        evt.preventDefault();
        this.option.items.push(this.textBox.value);
    },
    render: function () {
        return '<div>\
                  <h3>TODO</h3>\
                  <ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>\
                  <form onsubmit="add(event)" >\
                   <input nc-id="textBox" type="text"  />\
                   <button>Add #{{items.length}}</button>\
                 </form>\
               </div>';
    },
    style: function () {
        return 'h3 { color:red; }\
                button{ color:green;}';
    }
});
var todoApp = new TodoApp({ items: [] }, '#container');

todoApp.option.items.push('Nuclear');
todoApp.option.items.push('Hello World!');

style要领内的款式自会对本身见效,不会污染其他组件。能够操纵对象实例option,option的变更会自动更新组件,属性设置>要领挪用。
双向绑定的优点之前写过一篇文章特地引见,从上面的例子也能可出:

  • 组件内部的代码更简约

  • 组件外部的代码更简约

严阵以待

壁垒:古代虎帐周围的围墙;威严:整洁,庄重。原指军事警觉周密。现也用来比方相互界线划得很清楚。
<template id="myTemplate">
    <style scoped>
        h3 { color:red; }
        button{ color:green;}
    </style>

    <div>
        <div>
            <h3>TODO</h3>
            <ul>{{#items}}<li>{{.}}</li>{{/items}}</ul>
            <form onsubmit="add(event)">
                <input nc-id="textBox" type="text">
                <button>Add #{{items.length}}</button>
            </form>
        </div>
    </div>
</template>

<script>
    var TodoApp = Nuclear.create({
        install:function() {
            this.todoTpl = document.querySelector("#myTemplate").innerHTML;
        },
        add: function (evt) {
            evt.preventDefault();
            this.option.items.push(this.textBox.value);
        },
        render: function () {
            return this.todoTpl;
        }
    });

    new TodoApp({ items: [] }, "#todoListContainer");
</script>

不必忧郁template标签的兼容性题目,Nuclear帮你处置惩罚好了。支撑一切当代浏览器(包含IE9+)。
Nuclear也在js里进行了动态插入了template { display: none !important; }。然则js还没实行到且浏览器不兼容template的话,用户会看到一闪而过的模板原始代码。
所以为了防止IE9一闪而过的模板原始代码直接显现,发起在head中到场。

<style>
    template { 
           display: none !important; 
    }
</style>

假如你像手Q hybrid运用那样只须要兼容webkit的话,生成支撑template,就不必到场上面的兼容款式。

巧夺天工

《庄子·达生》:“梓庆削木为鐻,鐻成,见者惊忧鬼神。”
var TodoApp = Nuclear.create({
    add: function (evt) {
        evt.preventDefault();
        this.option.items.push(this.textBox.value);
    },
    render: function () {
        return `<div>
                  <h3>TODO</h3>
                  <ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>
                  <form onsubmit="add(event)" >
                   <input nc-id="textBox" type="text"  />
                   <button>Add #{{items.length}}</button>
                 </form>
               </div>`;
    },
    style: function () {
        return `h3 { color:red; }
                button{ color:green;}`;
    }
});

人剑合一

剑修者最高境地,人既是剑,剑既是人,剑随心发,人随剑杀
var TodoApp = Nuclear.create({
    add: function (evt) {
        evt.preventDefault();
        this.option.items.push(this.textBox.value);
    },
    render: function () {
        return `<style scoped>
                  h3 { color:red; }
                  button{ color:green;}
                </style>
                <div>
                  <h3>TODO</h3>
                  <ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>
                  <form onsubmit="add(event)" >
                   <input nc-id="textBox" type="text"  />
                   <button>Add #{{items.length}}</button>
                 </form>
                </div>`;
    }
});

Nuclear从诞生,API简朴稳固,险些没怎样更改,内部是完成在不停的完美,API驱动非常重要,不能由于完成某些API难题而做任何让步,比方让运用框架的着多传个参数、多挪用一次要领,这都是设想的缺点。

Nuclear就是不让步的效果。由于简朴的设想,所以能够有许多壮大的弄法,待续…

广而告之

Nuclear Github: https://github.com/AlloyTeam/Nuclear

到场Nuclear,一同让组件化开辟体验越发舒服、温馨..

    原文作者:dntzhang
    原文地址: https://segmentfault.com/a/1190000005131327
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞