當你的後臺系統寫好,給測試大大驗收的時候。會發現他甩了一堆兼容性bug給你,在ie中打不開頁面啦、在360瀏覽器火狐ie佈局混亂啦、輸入框怎麼有難看的黃色背景啦、電話輸入框怎麼有醜陋的箭頭啦、字體溢出了啦等等等等...javascript
在開發時咱們都習慣在google瀏覽器進行調試,總所周知,google瀏覽器的對css三、html五、es6等的支持是徹底沒有問題的,因此咱們會忽略了其實在其餘瀏覽器對這些新特性不夠支持的問題,下面介紹我在開發後臺系統中使用的一些插件和一些小技巧,來讓你的後臺系統儘量多的向下向外兼容多版本瀏覽器~css
許多後臺系統都要求要作成響應式的,雖然咱們用的elementUI框架已經在響應式上面作了出色的處理,可是也只能解決一部分的問題。因此咱們須要使用rem。html
rem是CSS3新增的相對長度單位,是指相對於根元素html的font-size計算值的大小。簡單可理解爲屏幕寬度的百分比。vue
可是!可是!問題來了,那就是咱們其實用px開發習慣了,要改爲rem一時半會緩不過來,加上還要換算是吧。因此用rem還挺煩的。接下來主角就登場了,安利你們幾個插件,可以將你項目中的px轉換成rem,還能夠自定義換算基數等。html5
npm install --save lib-flexible
npm install --save-dev px2rem-loader postcss-plugin-px2rem
複製代碼
postcss-plugin-px2rem 是爲了在使用less或者sass的狀況下也能夠正常轉換 java
<meta name="viewport" content="width=device-width,initial-scale=1.0">
標籤使用lib-flexible插件,他會自動生成meta name="viewport"的標籤,因此咱們須要把原來有的刪除掉。自動生成標籤以後,lib-flexible會自動設置html的font-size爲屏幕寬度除以10,也就是1rem等於html根節點的font-size,若是你的設計稿寬度是750px,那font-size就會被設置爲75pxnode
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- <meta name="viewport" content="width=device-width,initial-scale=1.0"> -->
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>vuecli3-ele-admin-template</title>
</head>
<body>
<noscript>
<strong>We're sorry but vuecli3-ele-admin-template doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
複製代碼
在main.js全局引入lib-flexiblecss3
// 使用lib-flexible來解決移動端適配
import 'lib-flexible'
複製代碼
在vue.config.js新增px2rem的配置git
const path = require('path')
function resolve(dir) {
return path.join(__dirname, dir)
}
module.exports = {
publicPath: '/',
outputDir: 'dist', // 輸出文件目錄
assetsDir: 'assets', // 靜態資源文件夾
productionSourceMap: false,
devServer: {
port: 9566, // 端口號
open: true,
proxy: null // 設置代理
},
// 新增內容
css: {
loaderOptions: {
sass: { // 若是用的是less就改爲less
javascriptEnabled: true
},
postcss: {
plugins: [
require('postcss-plugin-px2rem')({
rootValue: 54, // 換算基數,默認100,自行根據效果調整。
mediaQuery: false, // (布爾值)容許在媒體查詢中轉換px。
minPixelValue: 3 // 設置要替換的最小像素值默認0,這裏表示大於3px會被轉rem。
})
]
}
}
},
// 新增結束
chainWebpack: config => {
// 新增內容
config.module
.rule('css')
.test(/\.css$/)
.oneOf('vue')
.resourceQuery(/\?vue/)
.use('px2rem')
.loader('px2rem-loader')
.options({
remUnit: 54
})
// 新增結束
config.module
.rule('svg')
.exclude.add(resolve('src/icons'))
.end()
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
}
}
複製代碼
官方文檔給出的配置項有這麼多:es6
{
rootValue: 100,
unitPrecision: 5,
propWhiteList: [],
propBlackList: [],
exclude:false,
selectorBlackList: [],
ignoreIdentifier: false,
replace: true,
mediaQuery: false,
minPixelValue: 0
}
複製代碼
咱們目前只用到了三個 那麼這些都是啥意思呢,一塊兒來康康
{ px: 50, rpx: 100 }
,那麼就意味着,在換算的時候,若是趕上單位是px那換算基數是50,若是趕上rpx那麼換算基數是100/(node_module)/
,就是說(node_module)中的樣式文件不進行替換,這文件夾裏能有啥,就是你引的插件嘛。排除這個文件夾的意思就是不對你引入的UI框架的樣式進行單位轉換。細心的小夥伴發現我這裏的rootValue轉換基數設置的是54,爲何涅?你運行項目,而後F12,會發現根元素html的font-size是54px。爲何!爲何明明前面說的是寬度除以10啊,我特喵的pc端寬度是1080啊,不該該是font-size:108px麼???
想知道答案的小夥伴就要去看看偉大的lib-flexible的源碼啦,lib-flexible裏頭有這麼一段代碼:
function refreshRem(){
var width = docEl.getBoundingClientRect().width;
if (width / dpr > 540) {
width = 540 * dpr;
}
var rem = width / 10;
docEl.style.fontSize = rem + 'px';
flexible.rem = win.rem = rem;
}
複製代碼
pc端的dpr是1,width / dpr確定是大於540的,因此lib-flexible會默認使用540px這個寬度,而後將屏幕寬度除以10做爲rem值,因此1rem = 54px。因此咱們將rootValue轉換基數設爲54剛恰好
康康添加了lib-flexible & px2rem以後,頁面在移動端的顯示效果如何:
好的,十分優秀。
當你寫完後臺系統以後,毛悶臺了喔,在線上把代碼一拉一部署,測試那邊說了,你這個頁面我瀏覽器打不開啊!你過去以後發現他用的ie不知道6仍是7仍是8測得你的網站。那麼問題來了,爲何會打不開呢?
緣由就是你的項目裏頭用了es6的promise,ie低版本對這個的支持不是特別好,這個問題很好解決,只須要引入兩個插件就能夠了。對自己代碼沒有其餘影響。
npm install --save es6-promise babel-polyfill
複製代碼
// 解決低版本瀏覽器不支持promise問題
import 'babel-polyfill'
import Es6Promise from 'es6-promise'
Es6Promise.polyfill()
複製代碼
// 。。。此處省略n個字符。。。
config.module
.rule('icons')
.test(/\.svg$/)
.include.add(resolve('src/icons'))
.end()
.use('svg-sprite-loader')
.loader('svg-sprite-loader')
.options({
symbolId: 'icon-[name]'
})
// 新增配置
config.entry.app = ['babel-polyfill', './src/main.js']
// 新增結束
}
}
複製代碼
不少時候,像flexBox或者transform這樣樣式,在不一樣瀏覽器下面有不一樣的寫法,正常來講咱們每次用到其中一個的時候都須要寫這麼長一大串:
<style lang="scss">
.flex-box {
display: -webkit-box;
display: -moz-box;
display: -webkit-flex;
display: -moz-flex;
display: -ms-flexbox;
display: flex;
-webkit-justify-content: center;
-webkit-box-pack: center;
-moz-justify-content: center;
-moz-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
-webkit-align-items: center;
-webkit-box-align: center;
-moz-align-items: center;
-moz-box-align: center;
-ms-flex-align: center;
align-items: center;
-webkit-box-direction: normal;
-webkit-box-orient: vertical;
-webkit-flex-direction: column;
-moz-flex-direction: column;
-moz-box-orient: vertical;
-ms-flex-direction: column;
flex-direction: column;
}
</style>
複製代碼
暈,我只是想要用一下flex佈局啊。。
通過評論區小夥伴的提醒,這裏有一個很棒的插件可使用,他能夠自動給你的項目增長兼容前綴,須要添加的瀏覽器兼容前綴由你自由配置。咱們只需:
cnpm install --save-dev autoprefixer
複製代碼
// ...省略前面省略
css: {
loaderOptions: {
sass: { // 若是用的是less就改爲less
javascriptEnabled: true
},
postcss: {
plugins: [
// 新增內容
require('autoprefixer')({}),
// 新增結束
require('postcss-plugin-px2rem')({
rootValue: 54, // 換算基數,默認100,自行根據效果調整。
mediaQuery: false, // (布爾值)容許在媒體查詢中轉換px。
minPixelValue: 3 // 設置要替換的最小像素值默認0,這裏表示大於3px會被轉rem。
})
]
}
}
},
// ...省略後面省略
複製代碼
在package.json中新增
"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8",
"iOS >= 8",
"Firefox >= 20",
"Android >= 4.4"
]
複製代碼
接下來就是見證奇蹟的時刻,從新npm run serve一下,你就發現全部兼容樣式前面都加上前綴啦~
關於以前的手寫mixin的方法,我仍是建議你們可以多封裝,不論是業務代碼上仍是樣式代碼上,這樣能夠增長代碼的複用率,讓你的代碼看起來更加輕盈。像一些使用率比較多的樣式塊,可使用mixin封裝起來,須要時include就行啦,也是十分方便的。
舉個栗子
/* 背景自適應容器大小 */
@mixin bgCover($url) {
background-image: url($url);
background-repeat: no-repeat;
background-size: cover;
background-position: 0 center;
}
@mixin noData($url) {
width: 100%;
font-size: 14px;
text-align: center;
color: #666;
line-height: 60px;
}
複製代碼
<style lang="scss">
@import '~@/styles/mixin';
.no-data {
@include noData;
}
</style>
複製代碼
不少標籤都有一些奇奇怪怪的默認樣式,在不一樣的瀏覽器下面默認樣式還不同,爲了統一性。咱們須要覆蓋掉默認樣式。其實這一塊,elementUI已經考慮到了,在styles目錄下面的index.scss文件就是用來覆蓋默認樣式的。有須要覆蓋掉的默認樣式,能夠在裏面已有代碼的基礎上再新增。分享兩個典型的:
input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
}
input[type="number"] {
-moz-appearance: textfield;
}
複製代碼
input::-moz-placeholder{color:rgb(204, 204, 204)} //Firefox
input::-webkit-input-placeholder{color:rgb(204, 204, 204)} //Chrome,Safari
input:-ms-input-placeholder{color:rgb(204, 204, 204)} // ie
textarea::-moz-placeholder{color:rgb(204, 204, 204)} //Firefox
textarea::-webkit-input-placeholder{color:rgb(204, 204, 204)} //Chrome,Safari
textarea:-ms-input-placeholder{color:rgb(204, 204, 204)} // ie
複製代碼
國產瀏覽器大可能是雙內核,甚至更多,例如360瀏覽器、QQ瀏覽器之類。這些瀏覽器通常會有一個Chromium內核(極速模式。Chromiu就是Chrome使用的內核。);一個IE內核(IE模式);有的甚至還有一個修改過的IE內核(兼容模式)。
咱們建立的項目,默認有一個控制切換瀏覽器內核的meta標籤<meta http-equiv="X-UA-Compatible" content="IE=edge">
運行網站的時候強制切換爲該瀏覽器所擁有的最高版本IE內核,因此在qq瀏覽器或者360瀏覽器裏頭打開項目,會發現瀏覽器用的是IE模式或者兼容模式。
由於項目是用chrome調試的,因此在Chromium內核下擁有最優體驗,咱們須要用代碼讓瀏覽器可以改變一下模式。具體作法就是:
新增meta標籤,告訴瀏覽器優先使用何種內核
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<!-- 新增內容 -->
<!-- 強制Chromium內核,做用於360瀏覽器、QQ瀏覽器等國產雙核瀏覽器 -->
<meta name="renderer" content="webkit"/>
<!-- 強制Chromium內核,做用於其餘雙核瀏覽器 -->
<meta name="force-rendering" content="webkit"/>
<!-- 若是有安裝 Google Chrome Frame 插件則強制爲Chromium內核,不然強制本機支持的最高版本IE內核,做用於IE瀏覽器 -->
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"/>
<!-- 新增結束 -->
<!-- <meta name="viewport" content="width=device-width,initial-scale=1.0"> -->
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>vuecli3-ele-admin-template</title>
</head>
<body>
<noscript>
<strong>We're sorry but vuecli3-ele-admin-template doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
複製代碼
清一下瀏覽器緩存,從新運行項目,就會發如今360瀏覽器、QQ瀏覽器下已經變成Chromium內核的極速模式了~美得很~
暫時就先想到這些啦,後面想到我再繼續補充~~ 還有不少細節的東西沒有詳細寫出來,我這裏貼一下項目地址,有興趣的能夠看一看哦~