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