營運智享遇到的問題(前端)
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會将&轉義為&,請求圖檔資源會出錯
指派後 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);