引入babel-polyfill和es6-promise两个插件,将ES6语法转化为ES5javascript
cnpm install --save-dev babel-polyfill es6-promise
复制代码
// 解决低版本浏览器不支持promise问题 import 'babel-polyfill' import Es6Promise from 'es6-promise' Es6Promise.polyfill() 复制代码
// ...省略 chainWebpack: config => { // 新增 config.entry.app = ['babel-polyfill', './src/main.js'] } // ...省略 复制代码
不可能为了兼容一个IE9,而下降了其它主流版本浏览器下的页面体验,因此我会使用CSS Hack,在IE9时再去加载兼容文件和布局。css
CSS hack是经过在CSS样式中加入一些特殊的符号,让不一样的浏览器识别不一样的符号,以达到应用不一样的CSS样式的目的 html
由于我是针对IE9,因此我采用了IE浏览器专有的Hack方式:条件注释法。前端
主要用来存放为了兼容ie9而添加的css和js补丁文件等vue
ie9样式补丁文件java
<head> // ... <!--[if lte IE 9]> <link href="./ie9/ie9.css" rel="stylesheet"></link> <![endif]--> </head> 复制代码
这样作了以后,在浏览器是ie9时,会自动加载ie9.css文件,而在其余浏览器下则会忽略这行代码ios
巧用position、float、display:inline-block
属性灵活修改布局git
background: linear-gradient(...)
正常:es6
background: linear-gradient(180deg, #1A74E4, #2599F0); 复制代码
ie9兼容写法:github
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr=#1A74E4, endColorstr=#2599F0); -ms-filter: "progid:DXImageTransform.Microsoft.gradient (GradientType=1, startColorstr=#1A74E4, endColorstr=#2599F0)"; 复制代码
缘由:包裹表格的容器用了绝对或者相对定位,通常就是
.el-table
用了相对定位,但没有设置层级,在ie中z-index层级下降。
解决方法:只须要将表格所属的父级或者祖父容器的z-index调高就行,将
.el-table
设置为10以后,卡顿问题解决
用了一个大佬封装的js,稍微改了一下,能支持正常状况下placeholder的显示,好比登陆注册页。
brower-version.js:
export default function browerVersion() { var ua = navigator.userAgent var ver = 0 var versiondata var versionbool if (ua) { if (ua.match(/MSIE\s+([\d]+)\./i)) { ver = RegExp.$1 } else if (ua.match(/Trident.*rv\s*:\s*([\d]+)\./i)) { ver = RegExp.$1 } } versiondata = parseInt(ver) if (versiondata <= 9 && versiondata !== 0) { versionbool = true } else { versionbool = false } // versionbool true: 低于ie9 false: ie10+ return versionbool } 复制代码
main.js
import browerVersion from '@/assets/utils/brower-version.js' const isIE9 = browerVersion() Vue.prototype.$browerVersion = isIE9 复制代码
/assets/utils/ie-placeholder.js
在App.js调用ie-placeholder.js定义的方法 初始化各input的placeholder
<script>
import iePlaceholders from '@/assets/utils/ie-placeholder'
export default {
name: 'App',
mounted() {
if (this.$browerVersion) {
iePlaceholders()
}
}
}
</script>
复制代码
可是涉及到elementUI的其余组件,好比日期选择,好比级联选择,就会有点问题。这里的建议仍是在ie9下不要纠结显示placeholder,体验太差了。
在ie10+的版本咱们能够经过
::-ms-clear,
::-ms-reveal{
display:none !important;
}
复制代码
这段代码来隐藏,可是我发如今ie9下面是没用的。只能经过在输入框末尾增长一个和背景同色的块来遮掉,可是这样会影响输入的内容的全显示,个人作法是就让它留着,影响不大。
当input的type属性为number时,仍是能够任意输入其余符号。。我选择在ie9放弃number限制的挣扎
在ie9下,el-upload是没法使用的。我引入了可以兼容ie9的其余上传插件,当浏览器为ie9时就用自定义的上传组件,当非ie9时就保持原来的el-upload组件。
用vue-upload-component替代el-upload
cnpm install vue-upload-component --save
复制代码
能够全局引入也能够局部引入,由于我只有两个地方用到了上传组件,因此我选择在用到的页面引入。
<template> <!-- 省略n行代码 --> <file-upload v-if="$browerVersion" ref="compatibleUpload" v-model="compatibleFiles" :post-action="`${API.UploadImg}`" @input-file="inputFile" > <el-button :loading="uploadLoading" :icon="imgName ? '' : 'el-icon-upload2'" :title="imgName ? '从新选择' : '选择图片'" plain > {{ !imgName ? '上传图片' : imgName }} </el-button> </file-upload> <!-- 省略n行代码 --> </template> <script> import VueUploadComponent from 'vue-upload-component' export default { components: { FileUpload: VueUploadComponent }, data() { imgSizeLimit: 2, imgName: '', imgUrl: '', uploadLoading: false, compatibleFiles: [] }, methods: { inputFile(newFile, oldFile, prevent) { // 添加文件 if (newFile && !oldFile) { // 过滤不是图片后缀的文件 if (!/\.(jpg|png)$/i.test(newFile.name)) { this.$message.closeAll() this.$message.warning('只能上传jpg/png文件,请从新选择') return prevent } if (newFile.size > this.imgSizeLimit * 1024 * 1024) { this.$message.closeAll() this.$message.warning(`上传的图片的大于${this.imgSizeLimit}M,请从新选择`) return prevent } // 自动上传 if (Boolean(newFile) !== Boolean(oldFile) || oldFile.error !== newFile.error) { if (!this.$refs.compatibleUpload.active) { this.uploadLoading = true this.$refs.compatibleUpload.active = true } } } // 上传完成 if (newFile && oldFile && !newFile.active && oldFile.active) { // 得到相应数据 this.uploadLoading = false this.$refs.compatibleUpload.remove(newFile) // 删除当前文件对象 let response = newFile.response if (Object.prototype.toString.call(response) !== '[object Object]') { response = (new Function('return ' + response))() } else { this.$message.closeAll() this.$message.error('图片上传失败, 请从新上传') } if ((response.resultCode === '1' || response.resultCode === 1) && response.data) { this.imgUrl = response.data this.imgName = newFile.name this.$message.closeAll() this.$message.success('图片上传成功') } else { this.imgUrl = '' this.imgName = '' this.$message.closeAll() let errorMsg = response.resultMessage ? response.resultMessage : '图片上传失败, 请从新上传' if (['10021'].includes(response.resultCode)) { errorMsg = `上传的图片的大于${this.imgSizeLimit}M,请从新选择` this.$message.warning(errorMsg) return } this.$message.error(errorMsg) } } } } } </script> 复制代码
具体用法请参考官方文档,这要注意若是让组件本身发起请求,就是使用post-action参数,则是用iframe模拟form表单提交数据的,用这种方式传给后台的数据就是formData格式,可是不能添加header请求头。若是非要有请求头,那就要使用custom-action自定义上传方法,可是自定义上传方法的话,接口参数就不能用formData格式来传给后台了,为啥?由于ie9不支持new FormData()。。
没错,在IE9如下是不支持JSON.parse方法来解析json字符串的,有两种方法来替代JSON.parse
function strToJson(str){ var json = eval('(' + str + ')'); return json; } 复制代码
可是出于安全性的考虑,建议尽可能不要使用eval,若是从第三方获取数据进行解析,会存在恶意脚本代码的风险。
function strToJson(str){ var json = (new Function("return " + str))(); return json; } 复制代码
这也不算只是ie9的问题了,ie内核都存在这个问题。当你请求接口时,请求地址和请求参数都没有变化的时候,ie是会默认从缓存中获取数据而不会从新发送请求的。
只要保证咱们每次的请求都是一个新的请求,就能够避免这种状况了,最简单的方式就是每次请求都带多一个时间戳参数,只须要在axios拦截器添加几行设置时间戳参数的代码便可
// request拦截器 service.interceptors.request.use( config => { const time = Date.parse(new Date()) / 1000 // 添加时间戳参数 if (config.method === 'post') { config.data = { ...config.data, t: time } } if (config.method === 'get') { config.params = { ...config.params, t: time } } return config }, error => { // Do something with request error return Promise.reject(error) } ) 复制代码
在咱们以前Q2建立的ie9文件夹下,新建ie9-oninput-polyfill.js文件
/* eslint-disable */ (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' && el.type === 'text')) { var ev = d.createEvent('CustomEvent'); ev.initCustomEvent('input', true, true, {}); el.dispatchEvent(ev); } }); })(document); 复制代码
<head> // ... <!--[if lte IE 9]> <link href="./ie9/ie9.css" rel="stylesheet"></link> <script src="./ie9/ie9-oninput-polyfill.js" type="text/javascript"></script> <![endif]--> </head> 复制代码
由于ie9一下不支持new Blob,因此不能将二进制文件流转为文件下载。解决方法是让后台改接口,不要传二进制文件流过来,直接给前端传文件下载连接
解决方法:
.el-table .caret-wrapper {
display: inline-block;
}
.el-table .sort-caret{
display: block;
}
复制代码
好了,暂时只想到这些,后续有遗漏的会继续补充~