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

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

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

      observejs改善組件編程體驗

      2015-05-18 08:49  【當耐特】  閱讀(1915)  評論(4)    收藏  舉報

      傳送門

      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

      主站蜘蛛池模板: 亚洲欧美自偷自拍视频图片| 亚洲精品日韩中文字幕| 丝袜美腿亚洲综合第一页| 韩国三级+mp4| 狠狠色狠狠色综合日日不卡| 国精产品999国精产| 精品国产这么小也不放过| 欧美日韩免费专区在线观看| 福利一区二区在线播放| 搡老熟女老女人一区二区| 国产伦码精品一区二区| 巨爆乳中文字幕爆乳区| 亚洲日本精品国产第一区| 性欧美videofree高清精品| 亚洲成片在线看一区二区| 久久国产精品老人性| 国产精品自拍视频我看看| 妺妺窝人体色www婷婷| 欧美不卡无线在线一二三区观| 无码国模国产在线观看免费| 亚洲乱熟乱熟女一区二区| 久久久久久久一线毛片| 亚洲精品麻豆一二三区| 潘金莲高清dvd碟片| 亚洲综合精品成人| 中文文字幕文字幕亚洲色| 国产成人精品午夜二三区| 五指山市| 中文字幕国产在线精品| 亚洲成年av天堂动漫网站| 加勒比亚洲视频在线播放| 怡春院久久国语视频免费| 亚洲国产中文字幕在线视频综合| 国产一区二区三区四区五区加勒比 | 亚洲精品男男一区二区| 柳河县| 在线国产精品中文字幕| 天堂va蜜桃一区二区三区| 国产69精品久久久久99尤物| 亚洲乱码av中文一区二区| 国产揄拍国产精品|