前端項目發佈後的問題總結

引言

最近作的項目已經接近尾聲,剛剛發到線上,回顧和總結一下這段時間遇到的問題和我的的一些想法。vue

select下拉修改和復原

//部分下拉選項
 <select  v-model="offer.measureUnit"  :data-index="index" v-select-change="offer.measureUnit">
                <option v-for="option in selectList['measureUnit']" v-bind:value="option" >
                        {{option}}
                 </option>
   </select>
  <!------------------------------------------->
 //select綁定的指令部分操做
  Vue.directive('select-change', {
      update: function (el,binding) {
         var oldValue=binding.oldValue;
          var newValue=binding.value;
          if(cache.submitFlag==true){
              return;
          }
          if(validatorRules.isBlank(oldValue)||validatorRules.isBlank(newValue)||(oldValue==newValue)){
              return;
          }
          if(el.getAttribute("measureUnitFlag")!="1"){
            var index= el.dataset.index;
                  new Dialog.tip({
                     ………………xxx邏輯
                      close(){
                                   el.setAttribute('measureUnitFlag','1');
                                    vm.formData[index].measureUnit=oldValue;
                              },
                  })
          }else {
              el.setAttribute("measureUnitFlag","0");
          }
          return false;
      }
  })
    <!------------------------------------------->
    恢復按鈕部分邏輯操做
               vm.formData=formDataFail;
                   Vue.nextTick(function () {
                        cache.submitFlag=false;
                  })

說明 需求:點擊select下拉選項,彈窗提示是否修改(select最多有200個)。實現:不適合用watch和computed,由於offer.measureUnit太多,且每一個都是獨立的不一樣的響應式屬性,考慮用指令,點擊恢復按鈕,列表從新渲染,此時指令會所有執行一遍,由於指令是在同一個組件模板中。經過在指令中比較先後值,以及設置cache.submitFlag避免沒必要要更新致使的彈窗,渲染。渲染完畢,復原submitFlag,防止select下拉選項單個點時擊失效;measureUnitFlag是爲了防止點擊同一個下拉選項時,在彈窗邏輯中點擊不修改賦原值時重複彈窗狀況。node

知識點1 指令的原理,在vue2中是函數式組件(就是說模板->render函數),因爲數據變化,致使依賴watcher-->update(),在每次組件經vdom diff,update後綁定在組件上的指令,只要組件中響應式屬性有一個更新,指令所有執行一遍.
知識點2 nextTick的機制webpack

export function queueWatcher (watcher: Watcher) {
  const id = watcher.id
  //這裏保證了相同的watcher只有一個會被加入到異步隊列中,
  //雖然第一個watcher會放進去,可是對dom的操做是在nextTick異步操做中,因此最終執行依賴的update方法時,取的必定是最新的data值。
  if (has[id] == null) {
    has[id] = true
    if (!flushing) {
      queue.push(watcher)
    } else {
      //對應watch裏面觸發watch的狀況,已經刷新的話,根據watcher標識的id刪除watcher
      let i = queue.length - 1
      while (i >= 0 && queue[i].id > watcher.id) {
        i--
      }
      queue.splice(Math.max(i, index) + 1, 0, watcher)
    }
    // queue the flush
    if (!waiting) {
      waiting = true
      nextTick(flushSchedulerQueue)  //異步隊列執行  將waiting和flushing都設爲false
    }
  }
}
而後nextTick(flushSchedulerQueue)-->三種兼容機制實現異步處理(基於優先級順序依次是Promise、MutationObserver、setTimeout)-->nextTickHandler()-> watcher.run()

打包問題

由於幾個項目依賴一個公共目錄,項目1是基於webpack1,項目2是gulp。依賴的公共目錄在被import時能被打包,可是不能編譯。當時沒找到緣由,統一改爲webpack2能夠了,最後作項目3時,基於vue2腳手架,出現一樣問題,探索一番,找到緣由,include致使能打包可是不能編譯。web

{
        test: /\.js$/,
        loader: 'babel-loader',
         exclude: /node_modules/,
        // include: [resolve('src'), resolve('test')],
        options: {
          presets: [
            ['es2015']
          ]
        }
 }

數據校驗

數據200條校驗,在錯誤多時要進行大量出錯樣式渲染,比較卡,改爲異步(基於setTimeout)單條校驗渲染,同時搭配上進度條動態展現處理過程,解決以上問題。編程

bug

get請求在ie和360兼容模式下屢次操做被緩存,接口維護以前的,以前沒測出來,發到線上測試驗證時發現這個問題,同事一神助攻,幫助我快速定位找到這個bug,這個bug暴露我ie下調試工具使用欠缺,指的是win7上ie調試工具,我平時也沒用到過。而後解決方式能夠加時間戳或者改爲post請求或者後端設置禁止緩存的header。json

require.ensure

require.ensure只能是用來實現按需加載,同時具備代碼分割的做用,不能實現並行加載,若是要實現並行而且按順序能夠用瀏覽器自己的機制。webpack的require.ensure底層是經過jsonp+promise的方式,下面是我寫的例子被編譯後source部分截取,展現出來以便更好的說明問題。gulp

_//1:__webpack_require__.e 加載chunk.js 異步(動態建立script)的方式,這個操做被封裝成promise返回_
__webpack_require__.e/* require.ensure */(0).then((function (require) {
    console.log("begin");
    var module2 = __webpack_require__(2);
   
  }).bind(null, __webpack_require__)).catch(__webpack_require__.oe);
  
_  ---------------------------
 // 2:jsonp方式,主要功能是安裝chunk_
   window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {
       var moduleId, chunkId, i = 0, resolves = [], result;
       for(;i < chunkIds.length; i++) {
          chunkId = chunkIds[i];
          if(installedChunks[chunkId])
             resolves.push(installedChunks[chunkId][0]);
          installedChunks[chunkId] = 0;
       }
       
       if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);
       while(resolves.length)
          resolves.shift()();  _//3:執行第一步promise的resolve方法,從而能夠繼續執行then當中的業務邏輯。_
  
    };

開發

合理的使用dev-server的熱加載機制,優化的開發配置提高開發效率;合理的使用mixins選項,模塊化拆分封裝功能;利用函數式思想,封裝抽象函數單元,業務相近的一組功能封裝成一個模塊;關鍵變量以及邏輯單元加上必要註釋,規範的編程風格等。感悟:之後我在code時,half or one day time,先在思想中先大體走一遍,作好完善的前期項目規劃-->技術選型、結構組織、難優化點、可概括的抽象功能等等 -->A good beginning is half of success.後端

總結

幾乎沒有實現不了的視覺和交互需求,只有小部分實現起來需考慮時間成本問題。規範、TDD、性能、開發效率等等都追求完美有困難,找到一個良好的動態平衡點很重要。路漫漫其修遠,吾將上下而求索。promise

相關文章
相關標籤/搜索