是时候亮出这张图了: 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布局也不错。