打造vuecli3+element後臺管理系統(五)幾個小技巧

當你的後臺系統寫好,給測試大大驗收的時候。會發現他甩了一堆兼容性bug給你,在ie中打不開頁面啦、在360瀏覽器火狐ie佈局混亂啦、輸入框怎麼有難看的黃色背景啦、電話輸入框怎麼有醜陋的箭頭啦、字體溢出了啦等等等等...

在開發時我們都習慣在google瀏覽器進行調試,總所周知,google瀏覽器的對css3、html5、es6等的支持是完全沒有問題的,所以我們會忽略了其實在其他瀏覽器對這些新特性不夠支持的問題,下面介紹我在開發後臺系統中使用的一些插件和一些小技巧,來讓你的後臺系統儘可能多的向下向外兼容多版本瀏覽器~

一、用rem代替px

許多後臺系統都要求要做成響應式的,雖然我們用的elementUI框架已經在響應式上面做了出色的處理,但是也只能解決一部分的問題。所以我們需要使用rem。

1.1 什麼是rem

rem是CSS3新增的相對長度單位,是指相對於根元素html的font-size計算值的大小。簡單可理解為屏幕寬度的百分比。

但是!但是!問題來了,那就是我們其實用px開發習慣了,要改成rem一時半會緩不過來,加上還要換算是吧。所以用rem還挺煩的。接下來主角就登場了,安利大家幾個插件,能夠將你項目中的px轉換成rem,還可以自定義換算基數等。

1.2 使用lib-flexible & px2rem自動轉換px為rem,解決響應式問題

1.2-1 引入lib-flexible 和 px2rem

npm install --save lib-flexible
npm install --save-dev px2rem-loader postcss-plugin-px2rem
複製代碼

postcss-plugin-px2rem 是為了在使用less或者sass的情況下也可以正常轉換

1.2-2 刪除或註釋index.html中的 標籤

使用lib-flexible插件,他會自動生成meta name="viewport"的標籤,所以我們需要把原來有的刪除掉。自動生成標籤之後,lib-flexible會自動設置html的font-size為屏幕寬度除以10,也就是1rem等於html根節點的font-size,如果你的設計稿寬度是750px,那font-size就會被設置為75px









複製代碼

1.2-3 入口文件引入lib-flexible

在main.js全局引入lib-flexible

// 使用lib-flexible來解決移動端適配
import 'lib-flexible'
複製代碼

1.2-4 新增配置

在vue.config.js新增px2rem的配置

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]'
})
}
}
複製代碼

1.2-5 康康postcss-plugin-px2rem的配置項

官方文檔給出的配置項有這麼多:

{
rootValue: 100,
unitPrecision: 5,
propWhiteList: [],
propBlackList: [],
exclude:false,
selectorBlackList: [],

ignoreIdentifier: false,
replace: true,
mediaQuery: false,
minPixelValue: 0
}
複製代碼

我們目前只用到了三個 那麼這些都是啥意思呢,一起來康康

  • rootValue 轉換基數,類型可以是Number也可以是Object,默認是100
  • 如果你傳的是一個Object,例如 { px: 50, rpx: 100 } ,那麼就意味著,在換算的時候,如果遇上單位是px那換算基數是50,如果遇上rpx那麼換算基數是100
  • unitPrecision 單位精度,Number類型,簡單的說就是轉換之後的rem要保留幾位小數,默認保留5位的哈
  • propWhiteList 轉換的白名單,Array類型,裡面包含了可以被轉換的css屬性
  • 默認是個空數組哦, 意思就是不用唄,就是說css裡所有的屬性,都可以進行轉換
  • 裡面的屬性值必須精確匹配,使用了白名單之後,意味著只有白名單裡頭的屬性可以轉換了。感覺這個白名單會比較少用到的說
  • propWhiteList 轉換的黑名單,和白名單相反嘛,黑名單裡頭的css屬性是不會進行轉換的
  • exclude 排除的文件夾,是正則表達式。比如說寫了/(node_module)/,就是說(node_module)中的樣式文件不進行替換,這文件夾裡能有啥,就是你引的插件嘛。排除這個文件夾的意思就是不對你引入的UI框架的樣式進行單位轉換。
  • selectorBlackList 選擇器黑名單,Array類型。和上面那個屬性黑名單大同小異,不同的是這裡忽略轉換的依據是css選擇器。
  • 如果是['body'],數組元素是單純的字符串,意思就是排除class為body的轉換,即忽略.body下的所有屬性的轉換。
  • 如果是[/^body$/]醬的,數組元素是一個正則表達式,他排除的就是body標籤,即忽略body標籤下的所有屬性的轉換。
  • ignoreIdentifier 默認是false,也可以是String類型,當是某個css屬性名的時候,意思就是忽略這個屬性的轉換。如果你想忽略的屬性只有那麼一個,而不是一連串的時候,就可以用它。當啟用這個的時候,replace會自動變成true的哈
  • replace 默認是true,Boolean類型,表示直接替換包含REM的規則,而不是添加回調函數
  • mediaQuery Boolean類型,默認是false,表示是否允許在@media查詢中進行轉換
  • minPixelValue Number類型,表示開始轉換的最小值,默認是0,意思就是大於0px的長度都進行轉換

細心的小夥伴發現我這裡的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之後,頁面在移動端的顯示效果如何:

打造vuecli3+element後臺管理系統(五)幾個小技巧

打造vuecli3+element後臺管理系統(五)幾個小技巧

好的,十分優秀。

二、解決低版本ie打不開頁面的問題

當你寫完後臺系統之後,毛悶臺了喔,在線上把代碼一拉一部署,測試那邊說了,你這個頁面我瀏覽器打不開啊!你過去之後發現他用的ie不知道6還是7還是8測得你的網站。那麼問題來了,為什麼會打不開呢?

原因就是你的項目裡頭用了es6的promise,ie低版本對這個的支持不是特別好,這個問題很好解決,只需要引入兩個插件就可以了。對本身代碼沒有其他影響。

2.1 引入es6-promise & 和babel-polyfill依賴包

npm install --save es6-promise babel-polyfill
複製代碼

2.2 在入口文件main.js引入

// 解決低版本瀏覽器不支持promise問題
import 'babel-polyfill'
import Es6Promise from 'es6-promise'
Es6Promise.polyfill()
複製代碼

2.3 在vue.config.js新增配置

 // 。。。此處省略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']
// 新增結束
}
}
複製代碼

三、使用autoprefixer讓css屬性自動增加兼容前綴

很多時候,像flexBox或者transform這樣樣式,在不同瀏覽器下面有不同的寫法,正常來說我們每次用到其中一個的時候都需要寫這麼長一大串:

<style><br>.flex-box {<br> display: -webkit-box;<br> display: -moz-box;<br> display: -webkit-flex;<br> display: -moz-flex;<br> display: -ms-flexbox;<br> display: flex;<br> -webkit-justify-content: center;<br> -webkit-box-pack: center;<br> -moz-justify-content: center;<br> -moz-box-pack: center;<br> -ms-flex-pack: center;<br> justify-content: center;<br> -webkit-align-items: center;<br> -webkit-box-align: center;<br> -moz-align-items: center;<br> -moz-box-align: center;<br> -ms-flex-align: center;<br> align-items: center;<br> -webkit-box-direction: normal;<br> -webkit-box-orient: vertical;<br> -webkit-flex-direction: column;<br> -moz-flex-direction: column;<br> -moz-box-orient: vertical;<br> -ms-flex-direction: column;<br> flex-direction: column;<br>}<br>/<style>
複製代碼

暈,我只是想要用一下flex佈局啊。。

經過評論區小夥伴的提醒,這裡有一個很棒的插件可以使用,他可以自動給你的項目增加兼容前綴,需要添加的瀏覽器兼容前綴由你自由配置。我們只需:

3.1安裝autoprefixer依賴

cnpm install --save-dev autoprefixer 

複製代碼

3.2在vue.config.js引入

// ...省略前面省略
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。
})
]
}
}
},
// ...省略後面省略
複製代碼

3.3 在package.json中指定browserslist關鍵字

在package.json中新增

"browserslist": [
"> 1%",
"last 2 versions",
"not ie <= 8",
"iOS >= 8",
"Firefox >= 20",
"Android >= 4.4"

]
複製代碼

接下來就是見證奇蹟的時刻,重新npm run serve一下,你就發現所有兼容樣式前面都加上前綴啦~


關於之前的手寫mixin的方法,我還是建議大家能夠多封裝,不管是業務代碼上還是樣式代碼上,這樣可以增加代碼的複用率,讓你的代碼看起來更加輕盈。像一些使用率比較多的樣式塊,可以使用mixin封裝起來,需要時include就行啦,也是十分方便的。

舉個栗子

  1. 在styles的mixin.scss文件裡聲明一些常用的樣式塊
/* 背景自適應容器大小 */
@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;
}
複製代碼
  1. 在需要使用到mixin樣式的頁面引入,用mixin替換樣式塊
<style><br>@import '~@/styles/mixin';<br>.no-data {<br> @include noData;<br>}<br>/<style>
複製代碼

四、覆蓋默認樣式

很多標籤都有一些奇奇怪怪的默認樣式,在不同的瀏覽器下面默認樣式還不一樣,為了統一性。我們需要覆蓋掉默認樣式。其實這一塊,elementUI已經考慮到了,在styles目錄下面的index.scss文件就是用來覆蓋默認樣式的。有需要覆蓋掉的默認樣式,可以在裡面已有代碼的基礎上再新增。分享兩個典型的:

4.1 覆蓋掉input type=number時的箭頭

input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
}
input[type="number"] {
-moz-appearance: textfield;
}
複製代碼

4.2 改變Placeholder文字的顏色

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
複製代碼

暫時就先想到這些啦,後面想到我再繼續補充~~ 還有很多細節的東西沒有詳細寫出來,我這裡貼一下項目地址,有興趣的可以看一看哦~

  • 一個基於vuecli3和vue-admin-templ


分享到:


相關文章: