引入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;
}
複製代碼
好了,暫時只想到這些,後續有遺漏的會繼續補充~