是時候亮出這張圖了: vue
但是ie不是你不想兼容就不兼容啊。說多了都是淚。node
使用iview已經有一年多的時間。總的來講,iview仍是給個人工做帶來了很大的方便。webpack
主要的吐槽點就是文檔寫的不夠清楚。ios
好比組件的按需引入,寥寥數語,看完按照文檔引入了,結果控制檯一直報錯。git
而後到隔壁element一看,原來引入方式並非只有一種,有的須要經過vue.prototype.xxx這種方式。es6
還有對於兼容性的描述,github
你這麼一說我還覺得ie9直接引入polyfill就能夠用了呢,誰知道根本不行。在github上提issue又說不支持低版本ie了。web
根據個人經驗,不須要很大改動,兼容性大概ie10+,這也是element官方文檔上的兼容性。chrome
不知道iview這麼作是爲了吸引更多人入坑仍是怎麼回事,畢竟大多數開發者開發的時候都是先看官方文檔而不是先去github找issue。npm
吐槽歸吐槽,iview整體上仍是不錯的。下面說一下我在使用iview的過程當中所遇到的ie9+的兼容性問題及解決方案。
IE瀏覽器沒有內置Promise對象。不只如此,幾乎全部的ES6新增的方法在IE都不能用,此時你須要babel Polyfill
首先
npm install babel-polyfill --save
複製代碼
修改webpack.base.conf.js
修改前
entry: {
main: './src/main',
},
複製代碼
修改後
entry: {
main: ["babel-polyfill","./src/main"],
},
複製代碼
看到網上有的教程安裝完babel-polyfill又要安裝es6-prommise,只能說一句:多此一舉。
[Vue warn]: Error in directive transfer-dom inserted hook: "TypeError: 沒法獲取未定義或 null 引用的屬性「transfer」"
這是ie10及如下不支持dataset致使的,而iview的transfer-dom.js使用了這個屬性
解決辦法:在main.js加入以下代碼
if (window.HTMLElement) {
if (Object.getOwnPropertyNames(HTMLElement.prototype).indexOf('dataset') === -1) {
Object.defineProperty(HTMLElement.prototype, 'dataset', {
get: function () {
var attributes = this.attributes; // 獲取節點的全部屬性
var name = [];
var value = []; // 定義兩個數組保存屬性名和屬性值
var obj = {}; // 定義一個空對象
for (var i = 0; i < attributes.length; i++) { // 遍歷節點的全部屬性
if (attributes[i].nodeName.slice(0, 5) === 'data-') { // 若是屬性名的前面5個字符符合"data-"
// 取出屬性名的"data-"的後面的字符串放入name數組中
name.push(attributes[i].nodeName.slice(5));
// 取出對應的屬性值放入value數組中
value.push(attributes[i].nodeValue);
}
}
for (var j = 0; j < name.length; j++) { // 遍歷name和value數組
obj[name[j]] = value[j]; // 將屬性名和屬性值保存到obj中
}
return obj; // 返回對象
},
});
}
}
複製代碼
若是遇到如下錯誤:
錯誤1:「webpackJsonp」未定義
解決方案:
更改webpack-dev-server版本爲2.71或更低
npm install --save-dev webpack-dev-server@2.7.1
複製代碼
ie9是不支持requestAnimationFrame的,若是你使用了出現錯誤,那也不要緊,往下看就好了。
解決方案:添加如下代碼到main.js
// window.requestAnimationFrame多瀏覽器兼容問題補丁
// http://paulirish.com/2011/requestanimationframe-for-smart-animating/
// http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
// requestAnimationFrame polyfill by Erik Möller. fixes from Paul Irish and Tino Zijdel
// MIT license
(function () {
var lastTime = 0;
var vendors = ['ms', 'moz', 'webkit', 'o'];
for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame'] ||
window[vendors[x] + 'CancelRequestAnimationFrame'];
}
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = function (callback, element) {
var currTime = new Date().getTime();
var timeToCall = Math.max(0, 16 - (currTime - lastTime));
var id = window.setTimeout(function () { callback(currTime + timeToCall); },
timeToCall);
lastTime = currTime + timeToCall;
return id;
};
}
if (!window.cancelAnimationFrame) {
window.cancelAnimationFrame = function (id) {
clearTimeout(id);
};
}
}());
複製代碼
錯誤信息: 沒法獲取未定義或 null 引用的屬性「add」
沒法獲取未定義或 null 引用的屬性「remove」
若是你查看sourceMap發現了classList().add或classList.remove()等等,那確定是classList的問題了。
解決方案:添加如下代碼到main.js
if (!('classList' in document.documentElement)) {
Object.defineProperty(HTMLElement.prototype, 'classList', {
get: function () {
var self = this;
function update(fn) {
return function (value) {
var classes = self.className.split(/\s+/g);
var index = classes.indexOf(value);
fn(classes, index, value);
self.className = classes.join(' ');
};
}
return {
add: update(function (classes, index, value) {
if (!~index) classes.push(value);
}),
remove: update(function (classes, index) {
if (~index) classes.splice(index, 1);
}),
toggle: update(function (classes, index, value) {
if (~index) { classes.splice(index, 1); } else { classes.push(value); }
}),
contains: function (value) {
return !!~self.className.split(/\s+/g).indexOf(value);
},
item: function (i) {
return self.className.split(/\s+/g)[i] || null;
},
};
},
});
}
複製代碼
爲了更好的性能,咱們一般會採用路由懶加載。在單頁面應用中,每打開一個頁面基本上都只加載對應的資源文件。
若是跳轉到以前的頁面,一般頁面會採用緩存的資源文件,不會再次加載,這樣有效提升了頁面加載效率。
而若是採用location.href這種方式,頁面會所有刷新,從新下載全部頁面資源,不能很好的利用緩存。
這些能夠從chrome控制檯的network去查看。
更重要的是,若是直接採用location.href,ie瀏覽器可能會出現url變化頁面不刷新的狀況!
好比路由以下:
127.0.0.1:8080/#/home
127.0.0.1:8080/#/about
當前頁面是127.0.0.1:8080/#/home,
點擊按鈕跳轉
jump(){
location.href = '/#/about'
}
複製代碼
你會發現,瀏覽器地址欄url變了,而後頁面仍是home頁面! 因此你應該這樣用
jump(){
let url = '/#/about';
let path = url.split('#')[1];
this.$router.push(path);
}
複製代碼
這下跳轉就沒問題了。
固然,若是你有一些地方必需要使用location.href,好比你接入了第三方的一些服務,你沒法控制,也有解決方法:在vue根實例的created或者mounted生命週期添加以下代碼:
window.addEventListener('hashchange', () => {
let currentPath = window.location.hash.slice(1);
if (this.$route.fullPath !== currentPath) {
this.$router.push(currentPath);
}
}, false);
複製代碼
經過監聽hashchange,一旦發現當前頁面url與瀏覽器地址欄url不一樣,就調用vue的路由方法跳轉到地址欄url去。
若是目的頁面被keep-alive也會觸發這個方法,可是沒有影響。
若是頁面太長,咱們會加個滾動到頂部的按鈕
toTop(el){
el.scrollTo(0, 0);
}
複製代碼
誰知道ie下居然無動於衷!嘗試了一番,才發現是ie瀏覽器不支持scrollTo所致。
改爲這樣:
toTop(el){
if (el && el.scrollTo) {
el.scrollTo(0, 0);
} else {
el.scrollTop = 0;
}
}
複製代碼
ie也能夠滾動到頂部了。
這點是最坑的,頁面在ie10+打開雖然有些地方也會報錯,可是ie9徹底不會展現頁面,也就是說一個頁面都展現不出來!
控制檯報錯:訪問拒絕!
除此以外再無其餘信息。
反覆查看axios和vue的文檔,都說支持ie9.
這問題折磨了我很久,沒有具體錯誤信息,根本無從下手。
一個一個排查,不會是axios的問題吧。
一查發現果真是:ie8/9不支持cors跨域方案,取而代之的是ie的XDomainRequest方法
不想再去研究XDomainRequest方法了。直接用webpack-dev-server提供的服務器代理方法(前提是後臺已經配置好跨域),大概這樣:
devServer: {
port: 8080,
proxy: {
'/api': {
target: 'http://xx.xx.cn/',
pathRewrite: {'^/api' : ''},
changeOrigin: true
}
}
}
複製代碼
想要了解更多的能夠看看這個IE八、9 下的資源跨域請求
在ie瀏覽器下,若是直接使用例如new Date('2018-09-12'),ie會顯示Invalid Date,爲了保證在全部瀏覽器表現一致,應該採用new Date('2018/09/12')這種方式。
function IEVersion () {
var userAgent = navigator.userAgent; // 取得瀏覽器的userAgent字符串
var isIE = userAgent.indexOf('compatible') > -1 && userAgent.indexOf('MSIE') > -1; // 判斷是否IE<11瀏覽器
var isEdge = userAgent.indexOf('Edge') > -1 && !isIE; // 判斷是否IE的Edge瀏覽器
var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf('rv:11.0') > -1;
if (isIE) {
var reIE = new RegExp('MSIE (\\d+\\.\\d+);');
reIE.test(userAgent);
var fIEVersion = parseFloat(RegExp['$1']);
if (fIEVersion === 7) {
return 7;
} else if (fIEVersion === 8) {
return 8;
} else if (fIEVersion === 9) {
return 9;
} else if (fIEVersion === 10) {
return 10;
} else {
return 6;// IE版本<=7
}
} else if (isEdge) {
return 'edge';// edge
} else if (isIE11) {
return 11; // IE11
} else {
return -1;// 不是ie瀏覽器
}
};
複製代碼
用了translateX()發現ie9無動於衷,仍是乖乖用相對定位吧;
線性漸變linear-gradient()能夠用,可是ie不會識別的,因此先設置一個純色背景或圖片背景再設置線性漸變吧,否則ie背景設置不上。
flex佈局是挺爽,可是別用。想要一樣的效果,table佈局也不錯。