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