<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      代碼改變世界

      漫談Nuclear Web組件化入門篇

      2016-11-05 16:46  【當(dāng)耐特】  閱讀(1657)  評論(0)    收藏  舉報

      目前來看,團(tuán)隊內(nèi)部前端項目已全面實施組件化開發(fā)。組件化的好處太多,如:按需加載、可復(fù)用、易維護(hù)、可擴(kuò)展、少挖坑、不改組件代碼直接切成服務(wù)器端渲染(如Nuclear組件化可以做到,大家叫同構(gòu))...
      怎么做到這么強(qiáng)大的優(yōu)勢,來回憶下以前見過的坑,或者現(xiàn)有項目里的坑。

      CSS層疊樣式?保佑不要污染別的HTML!

      在web前端,一般一個組件必須要有骨架HTML和裝飾的CSS以及JS邏輯。而CSS要是可以是局部作用域那就再好不過了!就不用寫長長的前綴了,浪費帶寬不說,而且費勁。

      .ui-popup-arrow-xx-xxxxx-xxxx-container {
      
      }
      

      這回夠長了吧,不會污染別的HTML了吧。真的太長了,沒有辦法,因為CSS不是局部的,怕污染其他的HTML,規(guī)劃好長長的namespace、module是以前的最佳實踐。

      怎么優(yōu)雅綁定事件?只能定義在window下?

      如果HTML綁定的事件是局部作用域那就再好不過了!我真的見過模版代碼里出現(xiàn)下面的代碼:

      <div onclick="xxx()"></div>
      

      然后在js里找到了下面的代碼:

      <script>
      	window.xxx = function(){
          
          }
      </script>
      

      要綁定的事件一多,得污染多少全局變量啊。所以還有的工程師這么干:

      <div onclick="ns.xxx()"></div>
      <div onclick="ns.xxxx()"></div>
      

      然后在js里找到了下面的代碼:

      <script>
      	window.ns = {};
      
      	ns.xx = function(){
          
          }
          
          ns.xxx = function(){
          
          }
      </script>
      

      這里貌似比不設(shè)定namespace好很多,但是還是妥協(xié)的結(jié)果。一般希望能封裝成組件,組件的HTML里綁定的事件就是組件內(nèi)定義的事件,內(nèi)聚內(nèi)聚!!
      通過js動態(tài)綁定事件的壞處我以前專門寫了一篇文章來闡述,主要是lazy bind會導(dǎo)致用戶看到了頁面,但是頁面確無法響應(yīng)用戶的交互,這里不再闡述。

      需求變更?找不到在哪改代碼?

      大型項目如游戲什么的為啥都是面向?qū)ο笫降膶懛ǎ咳绻粋€組件剛好又能是一個Class那就再好不過,Class base可以更方便地抽象現(xiàn)實世界的物體及其屬性或者邏輯算法,所以甚至有些編程語言都是面向?qū)ο蟮?這里逆向邏輯),如JAVA、C#...整體過程式的代碼對于大型項目幾乎沒法維護(hù)(如基于jQuery就能容易寫出整體都是過程式的組織結(jié)構(gòu)),整體OO,局部過程式是可以接受的。

      組件需要嵌套?只能復(fù)制粘貼原組件?

      扁平無嵌套組件還是比較簡單,對模板的字符串處理下,把綁定的事件全指向組件自身定義的方法,生命周期也好處理。在真正的業(yè)務(wù)里經(jīng)常需要組件嵌套,這樣也更利于復(fù)用。雖然大量模板引擎支持引用子模板、共享數(shù)據(jù)等,但是組件是有生命周期的,模板嵌套不能真正解決組件嵌套的問題。能支持組件嵌套并且聲明式嵌套就那就再好不過了!

      數(shù)據(jù)變了?重新生成HTML替換一下?

      怎么替換?先查找dom?什么?你還在查找dom?你還在背誦CSS選擇器?替換一下?不能增量更新嗎?或者diff一下吧?不要每次全部替換啊!

      首屏太慢?以前抽象的組件沒法復(fù)用?

      什么?首屏太慢?改成直出(服務(wù)器渲染)?以前代碼沒法復(fù)用?要推翻重寫?什么?怎么搞?排期?產(chǎn)品不給排期?需求沒變?yōu)槭裁匆o排期?

      下面來看下Nuclear怎么解決上面問題。

      install Nuclear

      npm install alloynuclear
      

      Hello,Nuclear!

      var HelloNuclear = Nuclear.create({
          render: function () {
              return '<div>Hello , {{name}} !</div>';
          }
      })
      
      new HelloNuclear({ name: "Nuclear" }, "body");
      

      內(nèi)置了mustache.js無邏輯模板。

      事件綁定

      var EventDemo = Nuclear.create({
          clickHandler: function (evt, target, other1,other2) {
              //MouseEvent {isTrusted: true, screenX: 51, screenY: 87, clientX: 51, clientY: 21…}
              console.log(evt);
              //<div onclick="Nuclear.instances[0].clickHandler(event,this,'otherParameter1','otherParameter2')">Click Me!</div>
              console.log(target);
              //otherParameter1
              console.log(other1);
              //otherParameter2
              console.log(other2);
      
              alert("Hello Nuclear!");
          },
          render: function () {
              return '<div onclick="clickHandler(event,this,\'otherParameter1\',\'otherParameter2\')">Click Me!</div>'
          }
      })
      
      new EventDemo({ seen: true }, "body");
      

      條件判斷

      var ConditionDemo = Nuclear.create({
          render: function () {
              return '{{#seen}}\
                          <div>\
                              you can see me\
                          </div>\
                      {{/seen}}\
                      {{^seen}}\
                          <div>\
                              yan can not see me\
                          </div>\
                      {{/seen}}'
          }
      })
      
      var cd = new ConditionDemo({ seen: true }, "body");
      
      setTimeout(function () {
          cd.option.seen = false;
      }, 2000);
      

      2秒后改變seen,dom會自動變更。

      循環(huán)

      var LoopDemo = Nuclear.create({
          render: function () {
              return '<ul>{{#list}}<li>姓名:{{name}} 年齡:{{age}}</li>{{/list}}</ul>'
          }
      })
      
      var ld = new LoopDemo({
          list: [
              { name: "dntzhang", age: 18 },
              { name: "vorshen", age: 17 }
          ]
      }, "body");
      
      setTimeout(function () {
          //增加
          ld.option.list.push({ name: "lisi", age: 38 });
      }, 1000);
      
      setTimeout(function () {
          //修改
          ld.option.list[0].age = 19;
      }, 2000);
      
      setTimeout(function () {
          //移除
          ld.option.list.splice(0, 1);
      }, 3000);
      

      Array的變更也能監(jiān)聽到,能夠自動觸發(fā)Dom的變更。

      局部CSS

      <body>
      
          <div>I'm other div!! my color is not red!!</div>
      
          <script src="../dist/nuclear.js"></script>
      
          <script type="text/javascript">
              var ScopedCSSDemo = Nuclear.create({
                  clickHandler: function () {
                      alert("my color is red!");
                  },
                  render: function () {
                      return '<div onclick="clickHandler()">my color is red!</div>'
                  },
                  style: function () {
                      return 'div { cursor:pointer; color:red }';
                  }
              })
              //第三個參數(shù)true代表 增量(increment)到body里,而非替換(replace)body里的
              new ScopedCSSDemo ({ seen: true }, "body" ,true);
      
          </script>
      
      </body>
      

      組件外的div不會被組件內(nèi)的CSS污染。

      討厭反斜杠?

      討厭反斜杠可以使用 ES20XX template literals、或者split to js、css和html文件然后通過構(gòu)建組裝使用。也可以用template標(biāo)簽或者textare存放模板。

      <template id="myTemplate">
          <style>
              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" value="{{inputValue}}" 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.inputValue = "";
                  this.option.items.push(this.textBox.value);
              },
              render: function () {
                  return this.todoTpl;
              }
          });
      
          new TodoApp({ inputValue: "", items: [] }, "body");
      
      </script>
      

      組件嵌套

      <script>
          var TodoList = Nuclear.create({
              render: function () {
                  return '<ul> {{#items}} <li>{{.}}</li> {{/items}}</ul>';
              }
          });
      
      </script>
      
      <script>
          var TodoTitle = Nuclear.create({
              render: function () {
                  return '<h3>{{title}}</h3>';
              }
          });
      </script>
      
      <script>
      
          var TodoApp = Nuclear.create({
              install: function () {
                  //pass options to children
                  this.childrenOptions = [{ title: "Todo" }, { items: [] }];
                  this.length = 0;
              },
              add: function (evt) {
                  evt.preventDefault();
      
                  //this.nulcearChildren[1].option.items.push(this.textBox.value);
                  //or
                  this.list.option.items.push(this.textBox.value);
      
                  this.length = this.list.option.items.length;
                  this.textBox.value = "";
              },
              render: function () {
                  //or  any_namespace.xx.xxx.TodoList 對應(yīng)的 nc-constructor="any_namespace.xx.xxx.TodoList"
                  return '<div>\
                              <child nc-constructor="TodoTitle"></child>\
                              <child nc-constructor="TodoList"  nc-name="list"></child>\
                              <form onsubmit="add(event)" >\
                                <input nc-id="textBox" value="{{inputValue}}" type="text"  />\
                                <button>Add #'+ this.length + '</button>\
                               </form>\
                         </div>';
              }
          });
      
          new TodoApp({ inputValue: "" }, "body");
      </script>
      

      通過在父對象的install里設(shè)置this.childrenOptions來把option傳給子節(jié)點。

      服務(wù)器端渲染

      function todo(Nuclear,server) {
          var Todo = 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"  value="" />
                                <button>Add #{{items.length}}</button>
                            </form>
                          </div>`;
              },
              style: function () {
                  return `h3 { color:red; }
                         button{ color:green;}`;
              }
          },{
              server:server
          });
          return Todo;
      }
      
      if ( typeof module === "object" && typeof module.exports === "object" ) {
          module.exports =  todo ;
      } else {
          this.todo = todo;
      }
      

      通過第二個參數(shù)server來決定是服務(wù)器端渲染還是客戶端渲染。server使用的代碼也很簡單:

      var koa = require('koa');
      var serve = require('koa-static');
      var router = require('koa-route');
      var app = koa();
      var jsdom = require('jsdom');
      var Nuclear = require("alloynuclear")(jsdom.jsdom().defaultView);
      
      var Todo = require('./component/todo')(Nuclear,true);
      
      
      
      app.use(serve(__dirname + '/component'));
      
      app.use(router.get('/todos', function *(){
          var  str = require('fs').readFileSync(__dirname + '/view/index.html', 'utf8');
          var todo = new Todo({ items: ["Nuclear2","koa",'ejs'] });
          this.body = Nuclear.Tpl.render(str, {
              todo:  todo.HTML
          }); 
          Nuclear.destroy(todo);
      }));
      
      
      app.listen(3000);
      

      瀏覽器端使用的代碼:

      <!DOCTYPE html>
      <html>
      <head>
      </head>
      <body>
       {{{todo}}}
      
       <script src="./nuclear.js"></script>
       <script src="./todo.js"></script>
       <script>
          var Todo= todo(Nuclear);
          new Todo('body');
       </script>
      </body>
      </html>
      

      這樣,組件的代碼不需要任何變更就可以在server和client同時使用。

      Nuclear如何做到同構(gòu)的?

      內(nèi)置三條管線如下所示:

      比如一般前后端分離的開發(fā)方式,僅僅會走中間那條管線。而同構(gòu)的管線如下所示:

      這里前后后端會共用option,所以不僅僅需要直出HTML,option也會一并支持給前端用來二次渲染初始一些東西。

      Nuclear優(yōu)勢

      1.節(jié)約流量
      2.提升用戶體驗
      3.加載更加靈活
      4.Dom查找?guī)缀踅^跡
      5.搭積木一樣寫頁面
      6.提升代碼復(fù)用性
      7.可插拔的模板引擎
      8.Lazy CSS首屏更輕松
      9.Nuclear文件大小6KB (gzip)
      10.零行代碼修改無縫切到同構(gòu)直出
      ...
      ...

      Nuclear Github

      https://github.com/AlloyTeam/Nuclear

      主站蜘蛛池模板: 亚洲精品一区二区三天美| 免费无码观看的AV在线播放| 日本成熟少妇激情视频免费看| 性欧美丰满熟妇xxxx性| 99国产精品一区二区蜜臀| 久久天天躁狠狠躁夜夜躁2020| 蜜臀久久精品亚洲一区| 国产国产久热这里只有精品| 久久月本道色综合久久| 陇川县| 国产精品一区二区三区污| 免费国产午夜理论片不卡| 国产精品麻豆中文字幕| 性做久久久久久久| 永久国产盗摄一区二区色欲| 国产线播放免费人成视频播放 | 饥渴的熟妇张开腿呻吟视频| 亚洲三级香港三级久久| 不卡av电影在线| 国产欧美久久一区二区| 久久久无码精品国产一区| 97在线视频人妻无码| 亚洲熟妇久久精品| 精品久久久bbbb人妻| 亚洲色欲色欱WWW在线| 色综合色综合久久综合频道88| 久久99久久99精品免视看国产成人| 中国凸偷窥xxxx自由视频| 18禁国产一区二区三区| 亚洲人成网站18禁止无码| 亚洲区一区二区三区视频| 国产女主播喷水视频在线观看| 亚欧成人精品一区二区乱| 日韩有码精品中文字幕| 仲巴县| 99RE6在线观看国产精品| 爱啪啪av导航| 72种姿势欧美久久久久大黄蕉| 中文字幕日韩有码一区| 国产成人精品18| 蜜桃视频在线免费观看一区二区|