当你的后台系统写好,给测试大大验收的时候。会发现他甩了一堆兼容性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内核的极速模式了~美得很~
暂时就先想到这些啦,后面想到我再继续补充~~ 还有不少细节的东西没有详细写出来,我这里贴一下项目地址,有兴趣的能够看一看哦~