Q1. 不兼容ES6语法
引入babel-polyfill和es6-promise两个插件,将ES6语法转化为ES5
1-1、安装
cnpm install --save-dev babel-polyfill es6-promise
1-2、main.js引入
// 解决低版本浏览器不支持promise问题
import 'babel-polyfill'
import Es6Promise from 'es6-promise'
Es6Promise.polyfill()
在配置文件vue.config.js中引入
// ...省略
chainWebpack: config => {
// 新增
config.entry.app = ['babel-polyfill', './src/main.js']
}
// ...省略
Q2. CSS Hack
不可能为了兼容一个IE9,而降低了其它主流版本浏览器下的页面体验,所以我会使用CSS Hack,在IE9时再去加载兼容文件和布局。
CSS hack是通过在CSS样式中加入一些特殊的符号,让不同的浏览器识别不同的符号,以达到应用不同的CSS样式的目的
2-1、条件注释法
因为我是针对IE9,所以我采用了IE浏览器专有的Hack方式:条件注释法。
2-1.1、在public目录创建文件夹ie9
主要用来存放为了兼容ie9而添加的css和js补丁文件等
2-1.2、在ie9文件下创建css文件ie9.css
ie9样式补丁文件
2-1.3、在index.html的head中引入
<head>
// ...
<!--[if lte IE 9]> <link href="./ie9/ie9.css" rel="stylesheet"></link> <![endif]-->
</head>
这样做了之后,在浏览器是ie9时,会自动加载ie9.css文件,而在其他浏览器下则会忽略这行代码
Q3. 不兼容flex布局
巧用position、float、display:inline-block
属性灵活修改布局
Q4. 不兼容背景颜色的渐变写法background: linear-gradient(...)
正常:
background: linear-gradient(180deg, #1A74E4, #2599F0);
ie9兼容写法:
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr=#1A74E4, endColorstr=#2599F0);
-ms-filter: "progid:DXImageTransform.Microsoft.gradient (GradientType=1, startColorstr=#1A74E4, endColorstr=#2599F0)";
Q5、el-table数据量多(页面有滚动条时)在ie中会导致页面卡顿
原因:包裹表格的容器用了绝对或者相对定位,一般就是
.el-table
用了相对定位,但没有设置层级,在ie中z-index层级降低。
解决方法:只需要将表格所属的父级或者祖父容器的z-index调高就行,将
.el-table
设置为10之后,卡顿问题解决
Q6、不支持placeholder
用了一个大佬封装的js,稍微改了一下,能支持正常情况下placeholder的显示,比如登录注册页。
6-1、 在工具类文件夹下生成brower-version.js文件,用来判断浏览器版本
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
}
6-2、定义全局的浏览器是否是ie9版本的判断字段
main.js
import browerVersion from '@/assets/utils/brower-version.js'
const isIE9 = browerVersion()
Vue.prototype.$browerVersion = isIE9
6-3、工具类文件夹下创建ie-placeholder.js文件
/assets/utils/ie-placeholder.js
6-4、项目加载时就load一遍placeholder定义文件,为ie9下的input输入框加上placeholder
在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,体验太差了。
Q7、输入框自带有文本删除按钮和密码查看按钮
在ie10+的版本我们可以通过
::-ms-clear,
::-ms-reveal{
display:none !important;
}
这段代码来隐藏,但是我发现在ie9下面是没用的。只能通过在输入框末尾增加一个和背景同色的块来遮掉,但是这样会影响输入的内容的全显示,我的做法是就让它留着,影响不大。
Q8、input不支持type=number
当input的type属性为number时,还是可以任意输入其他符号。。我选择在ie9放弃number限制的挣扎
Q9、el-upload无法使用
在ie9下,el-upload是无法使用的。我引入了能够兼容ie9的其他上传插件,当浏览器为ie9时就用自定义的上传组件,当非ie9时就保持原来的el-upload组件。
用vue-upload-component替代el-upload
9-1、安装vue-upload-component
cnpm install vue-upload-component --save
9-2、引入
可以全局引入也可以局部引入,因为我只有两个地方用到了上传组件,所以我选择在用到的页面引入。
<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()。。
Q10、不支持JSON.parse
没错,在IE9以下是不支持JSON.parse方法来解析json字符串的,有两种方法来替代JSON.parse
10-1、eval方式
function strToJson(str){
var json = eval('(' + str + ')');
return json;
}
但是出于安全性的考虑,建议尽量不要使用eval,如果从第三方获取数据进行解析,会存在恶意脚本代码的风险。
10-2、new Function方式
function strToJson(str){
var json = (new Function("return " + str))();
return json;
}
Q11、vue项目在IE中自动读取缓存中的数据,不重新发请求
这也不算只是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)
}
)
Q11、在文本框中进行删除操作时,文本框的value不更新。
在我们之前Q2创建的ie9文件夹下,新建ie9-oninput-polyfill.js文件
11-1、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);
11-2、在css Hack中引入
<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>
Q12、不能导出二进制文件流
因为ie9一下不支持new Blob,所以不能将二进制文件流转为文件下载。解决方法是让后台改接口,不要传二进制文件流过来,直接给前端传文件下载链接
Q13、ie9下el-table的排序三角形错位
解决方法:
.el-table .caret-wrapper {
display: inline-block;
}
.el-table .sort-caret{
display: block;
}
好了,暂时只想到这些,后续有遗漏的会继续补充~
今天的文章IE9兼容爬坑总结—vuecli3+eleUI后台管理项目兼容IE9分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/19262.html