天天看點

vue + vue-resource + element-ui項目中遇到的問題總結

營運智享遇到的問題(前端)

vue + vue-resource + element-ui + vue-router + node.js + sass 

1. el-table filter tag 使用filter-method處理資料過濾,當該标簽下沒有資料時标簽切換不起作用

  解決: 1.用el-table的filter-change方法處理過濾邏輯,而不用el-table-column的filter-method方法;

        2.filter tag 設定預設值  

          初始化table時, filter-change和filter-method方法都不會調用,是以初始值設定隻是改變tag的UI狀态,擷取不到目前選擇的tag值,

          自己設定一個變量tagValue接收tag值,初始化時預設指派,在将顯示的label值相應formatter回顯,filter-change時指派相應的tagValue.

          :filter-value="filterValue" //tag選中狀态

  <el-table :data="list" @filter-change="filterChange">

    <el-table-column

      prop="tag"

      :label="tagNameFormatter"

      column-key="instiStatue"

      :filter-multiple="false"

      :filters="instiStatusList"

      :filter-method="filterTag"

      :filtered-value="filteredValue"

      :formatter="statusFormatter"

      filter-placement="bottom">

    </el-table-column>

  </el-table>

  tagNameFormatter(){//标簽名格式化

    let label = '';

    for(let i = 0 ; i < this.instiStatusList.length; i++){

      if(this.tagValue == this.instiStatusList[i].value){

        label = this.instiStatusList[i].text;

      }

    }

    return label;

  }

  filterChange(filter){//過濾(tag值改變) el-table方法

    this.filteredValue = [];

    this.filteredValue.push(filter.instiStatus[0]);

    this.tagValue = filter.instiStatus[0];

    this.getList();//查詢清單資料

  }

  filterTag(value, row){//過濾(tag值改變) el-table-column方法

  }

  statusFormatter(row, column){//狀态格式化

    let label = '';

    for(let i = 0 ; i < this.instiStatusList.length; i++){

      if(row.status == this.instiStatusList[i].value){

        label = this.instiStatusList[i].text;

      }

    }

    return label;

  }

2. loading遮罩層  ie9 遮罩全透明時,可以點選到遮罩層下的元素

  解決: .loading{background: rgba(255, 255, 255, 0.01);}

3. el-pagination ie9中頁碼和下一頁按鈕之間右側有很大一段空白

    解決: .el-pagination{

      .el-pager{

        li{

          float: left;

        }

      }

    }

4. 同一元件内多次調用pagination或切換tab頁pagination,pageSize置為1開始

  切換tab或pagination時将pagination.total = 0, pagination.pageNum = 1;

5. vue檢測變化的注意事項

  受現代 JavaScript 的限制 (而且 Object.observe 也已經被廢棄),Vue 不能檢測到對象屬性的添加或删除。由于 Vue 會在初始化執行個體時對屬性執行 getter/setter 轉化過程,是以屬性必須在 data 對象上存在才能讓 Vue 轉換它,這樣才能讓它是響應的。例如:

  var vm = new Vue({

    data:{

      a:1

    }

  })

  // `vm.a` 是響應的

  vm.b = 2

  // `vm.b` 是非響應的

  ue 不允許在已經建立的執行個體上動态添加新的根級響應式屬性 (root-level reactive property)。然而它可以使用 Vue.set(object, key, value) 方法将響應屬性添加到嵌套的對象上:

  this.$set(this.someObject,'b',2)

6. el-dialog 在ie9 左右不居中(transform 2d在ie9需加上-ms-字首)

  //解決方法: 不使用transform

  el-dialog(--small){

    width: 960px;

    height: 770px;

    //加上後三句代碼

    transform: none;

    position: static;

    margin: 5rem auto; // 5rem -> 按情況确定

  }

7. 解決輸入框背景顔色

  input:-webkit-autofill, textarea:-webkit-autofill, select:-webkit-autofill {

    -webkit-box-shadow: 0 0 0px 1000px #fff inset !important;

  }

8. ie9 v-for 渲染圖檔list 渲染85張左右後, 圖檔加載失敗

  (由src更新觸發的圖檔資源下載下傳不完整,圖檔顯示x),後面檢查發現是記憶體使用達到6.8G時

  圖檔加載就會失敗,是ie9浏覽器記憶體管理的問題,前端不需要解決,好像也解決不了..

9. ie9 hover元素高度無限增加問題 

  <div class='content'>

    <ul class="list">

      <li class="list_item"> ...... </li>

      <li class="list_item"> ...... </li>

      ......

    </ul>

  </div>

  .content{ width:100%; overflow:auto;}

  如果.list或者.list裡的元素設定了:hover的僞類(最常見的是滑鼠移入li,改行高亮)并在裡面寫有屬性,hover時就會出現.content高度一直增加的bug.

  bug觸發條件:

    1.父級設定overflow:auto;(準确來說是overflow-x:auto;),并且裡面的元素寬度超出父級寬度導緻橫向滾動條出現.

    2.父級元素的任意子元素設有:hover僞類且裡面設定有屬性(與原屬性不一緻).

    滿足這兩個條件,當觸發:hover僞類時,bug就會出現.

  解決方案:

    1.給父級設定overflow-x:scroll;(overflow:auto; => overflow-x:scroll;)

      .content{overflow-x:scroll;} -- (子元素寬度未超出父元素寬度時,也會顯示滾動條框,視覺體驗不太好)

    2.保證父級裡的元素不超出父級的寬度,不讓父級出現橫向滾動條.

    3.保證父級裡面的元素沒有:hover僞類(這個基本是不可能的..)

    4.給父級加高度

      .content(height:100%;)

10. ie9浏覽器對頻繁操作dom支援不好,會卡頓甚至卡死,盡量避免大量操作dom元素

11. nginx逾時設定(避免post請求處理時間過長,可能出現重複送出的問題)

  nginx 重試機制 proxy_next_upstream http_502 http_504 error timeout invalid_header;

  上面的配置表示,如果後端伺服器如下情況,将會把請求轉發到下一台後端伺服器上。

  error - 在連接配接到一個伺服器,發送一個請求,或者讀取應答時發生錯誤。

  timeout - 在連接配接到伺服器,轉發請求或者讀取應答時發生逾時。

  invalid_header - 伺服器傳回空的或者錯誤的應答。

  http_502 - 伺服器傳回502代碼。

  http_504 - 伺服器傳回504代碼。

  繼續檢視逾時時間   

  proxy_read_timeout 15;

  逾時時間為15s,是以後端伺服器響應慢,nginx沒有在15s内收到傳回的資料,是以将請求切換到下一台後端機器了,是以,同樣的情況下, 請求第二台後端機器時,也沒有在規定的時間内得到響應,是以又切換到第三台機器了,最終導緻短信發送了三次。 

  幾個參數說明:

  proxy_send_timeout     後端伺服器資料回傳時間(代理發送逾時時間)

  proxy_read_timeout      連接配接成功後,後端伺服器響應時間(代理接收逾時時間)

  proxy_connect_timeout    nginx連接配接後端的逾時時間,一般不超過75s

  如何解決呢?

    1、第一種辦法:因為後端機器無法再進行優化減少響應時間,是以可以更改nginx的逾時時間,将原本的15s更改為40s,這樣可以保證結果正常傳回。

    2、第二種辦法 :關閉自動切換到下台機器的功能,即将proxy_next_upstream配置為off。但是這樣雖然能解決問題,但是會導緻nginx的容錯能力下降。

    3、第三種辦法:從業務角度出發,本質上我們是需要隻發一次短信的。 是以可以采用分布式鎖的方式解決。

    以上現象還可能出現在以下的場景:

    1、上傳excel,然後服務端處理excel内容,插入到db裡面的時候,可能存在多次轉發導緻資料重複。

    2、post請求處理時間過長,可能出現重複送出的問題。

    本項目中設定了 proxy_send_timeout 180; proxy_read_timeout 180;

12. 後端取回的img URL 指派給img.src ,ie9會将&轉義為&amp;,請求圖檔資源會出錯

  指派後 imgUrl = imgUrl.replace(/amp;/g,'');

13. 遇到file元素設定cursor:pointer無效的情況

  input[type='file']{

    cursor: pointer;

    font-size: 0;

  }

  經測試,可以通過設定font-size:0;解決,chrome,ie9都可以适用

14. textarea解決maxlength的相容問題(ie9) 

  <textarea maxlength="10" onBlur="this.value=this.value.substring(0, 10)">

  <el-input type="textarea" model="textareaData" :maxlength="10" @blur="textareaData=textareaData.substring(0, 10)">

15. 檔案下載下傳

  1)模版類放前端靜态資源

   <a href="static/模版.xlsx" target="_blank" rel="external nofollow" download="模版.xlsx" target="_self"> </a>

   (download屬性設定檔案名強制下載下傳, ie9不支援)

  2) 檔案流下載下傳

    方法一: ie9下載下傳未能解決(識别不了檔案類型)

    Vue.http.get('url',{ responseType: 'blob'})

    .then(res => {

      const fileName = "考勤資訊.xlsx";

      const blob = response.data;

      if (window.navigator && window.navigator.msSaveOrOpenBlob) {

        window.navigator.msSaveOrOpenBlob(blob, fileName);

      } else {

        let elink = document.createElement("a"); // 建立a标簽

        elink.download = fileName;

        elink.style.display = "none";

        elink.href = URL.createObjectURL(blob);

        document.body.appendChild(elink);

        elink.click(); // 觸發點選a标簽事件

        document.body.removeChild(elink);

      }

    }).catch(err => {})

    方法二: 背景檔案流上傳到ecs(另一個存儲平台),取回檔案URL,傳回前端下載下傳

  3) URL下載下傳

      指定檔案mimeType的檔案,浏覽器會預設打開預覽,添加download屬性指定附件名稱後會下載下傳,ie9不支援 

      目前解決方法: <a href="url" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank" download="模版.xlsx"> </a>直接在新視窗打開,使用者另存為

16. 檔案上傳(使用的pulpload上傳插件)

  1) 檔案上傳傳回json資料,ie9提示檔案下載下傳,背景改content-type:text/html;

  2) ie9 ajax請求頭不能自定義設定,設定不了token,去掉權限校驗,可以通過multipart_params傳參;

  3) 檔案通過背景上傳到另一個平台,需要背景指定content-type,不然取回的檔案URL都是application/octet-stream類型

    (mp4/mp3 ie浏覽器(9,10,  11)識别不了mime類型,不能播放);

    指定類型後的檔案,取回的URL在浏覽器會直接打開,不能強制下載下傳,mp4在ie會提示下載下傳,

      目前解決方法: <a href="url" target="_blank" rel="external nofollow" target="_blank" rel="external nofollow" target="_blank"> </a>直接在新視窗打開,使用者另存為

  4) Chrome上傳zip格式檔案,彈出選擇檔案框要延遲7-8s,未解決

    https://blog.csdn.net/mingover/article/details/55045533

    http://www.piaoyi.org/computer/Google-Chrome-input-file-delay-3-5.html

  5) 使用plupload 

    import plupload from 'plupload'

    若要使用圖檔預覽 需引入 moxie.min.js(index.html)

  6) 多檔案上傳

    用pulpload 直接選擇多檔案,上傳時會調用多次上傳接口

    解決: 用pulpload上傳單個檔案,上傳多次,儲存傳回的fileId, 把fileIdList在通過另一個接口傳給背景關聯儲存.  

17. js實作不提示直接關閉網頁視窗

  function closePageForm(){

    window.opener=null;

    window.open('','_self');

    window.close();

  }

18. 解決 ie9 input input删除操作無法觸發資料變動監聽

  main.js裡添加

  (function (d) {

    if (navigator.userAgent.indexOf('MSIE 9') === -1) return;

    d.addEventListener('selectionchange', function() {

      var el = d.activeElement;

      if (el.tagName === 'TEXTAREA' || (el.tagName === 'INPUT')) {

        var ev = d.createEvent('CustomEvent');

        ev.initCustomEvent('input', true, true, {});

        el.dispatchEvent(ev);

      }

    });

  })(document);