一,创建一个vue项目
旧版本创建vue项目的命令为:
npm install -g @vue/cli-init
vue init webpack my-project
vue init
的运行效果将会跟 vue-cli@2.x
相同
vue create hello-world
随后会在命令行窗口让选择是使用包含了默认less+babel
的preset,还是手动自定义选取需要的特性。除此之外,还可以使用vue ui命令以图形化的界面创建和管理项目。
二, 移动端样式自适应
鉴于移动端屏幕种类繁多,UI出图一般都是针对750像素出图,并简单给出适配规则,前端开发人员就需要提供一套可用的适配方案,争取能够在最少的工作量下实现更加完善的适配。
常用的适配方案有rem和viewport两种,px2rem postcss-px-to-viewport
等插件可以提供px转rem和viewport的处理。
rem方案可以通过视口的大小动态设置根元素字体大小,所有元素都根据相对根元素大小编写样式。viewport方案实际上是更改视口的大小,根据视口和UI图宽度的比值进行等比缩放。这种方式破坏了完美视口,我们通常采用rem方式布局。
rem布局方案中,我们需要查询屏幕宽度然后设置根元素的font-size。一般的自适应方案中,字体根据屏幕大小而变化,这样在屏幕变宽时,字体会变大。事实上在有些时候并不适合我们的使用场景。索性淘宝提供了flexible方案,这种方案让字体大小适中保持在12px,但图片宽高根据html的字体变化来设定。
<script>
!function(a,b){function c(){var b=f.getBoundingClientRect().width;b/i>540&&(b=540*i);var c=b/10;f.style.fontSize=c+"px",k.rem=a.rem=c;if(window.navigator.userAgent.indexOf('Android')>-1&&window.navigator.userAgent.indexOf('Le')>-1){f.style.fontSize='30px';}}var d,e=a.document,f=e.documentElement,g=e.querySelector('meta[name="viewport"]'),h=e.querySelector('meta[name="flexible"]'),i=0,j=0,k=b.flexible||(b.flexible={});if(g){console.warn("将根据已有的meta标签来设置缩放比例");var l=g.getAttribute("content").match(/initial\-scale=([\d\.]+)/);l&&(j=parseFloat(l[1]),i=parseInt(1/j))}else if(h){var m=h.getAttribute("content");if(m){var n=m.match(/initial\-dpr=([\d\.]+)/),o=m.match(/maximum\-dpr=([\d\.]+)/);n&&(i=parseFloat(n[1]),j=parseFloat((1/i).toFixed(2))),o&&(i=parseFloat(o[1]),j=parseFloat((1/i).toFixed(2)))}}if(!i&&!j){var p=a.navigator.userAgent,q=(!!p.match(/android/gi),!!p.match(/iphone/gi)),r=q&&!!p.match(/OS 9_3/),s=a.devicePixelRatio;i=q&&!r?s>=3&&(!i||i>=3)?3:s>=2&&(!i||i>=2)?2:1:1,j=1/i}if(f.setAttribute("data-dpr",i),!g)if(g=e.createElement("meta"),g.setAttribute("name","viewport"),g.setAttribute("content","initial-scale="+j+", maximum-scale="+j+", minimum-scale="+j+", user-scalable=no"),f.firstElementChild)f.firstElementChild.appendChild(g);else{var t=e.createElement("div");t.appendChild(g),e.write(t.innerHTML)}a.addEventListener("resize",function(){clearTimeout(d),d=setTimeout(c,300)},!1),a.addEventListener("pageshow",function(a){a.persisted&&(clearTimeout(d),d=setTimeout(c,300))},!1),"complete"===e.readyState?e.body.style.fontSize=12*i+"px":e.addEventListener("DOMContentLoaded",function(){e.body.style.fontSize=12*i+"px"},!1),c(),k.dpr=a.dpr=i,k.refreshRem=c,k.rem2px=function(a){var b=parseFloat(a)*this.rem;return"string"==typeof a&&a.match(/rem$/)&&(b+="px"),b},k.px2rem=function(a){var b=parseFloat(a)/this.rem;return"string"==typeof a&&a.match(/px$/)&&(b+="rem"),b}}(window,window.lib||(window.lib={}));
</script>
这里我们设置了rem的基准单位,但是在样式编写中每一个像素都进行计算的话是非常繁琐的,使用px2rem插件可以帮助我们自动转换为rem,我们只需要根据UI图写px像素即可。
需要在vue.config.js文件中进行配置, postcss-px2rem-exclude 比 px2rem更好用的点在于可以设置不进行转换的黑名单,第三方UI库样式不会被污染。
const px2rem = require('postcss-px2rem-exclude')
const px2remConfig = px2rem({
remUnit: 75,
exclude: /node_modules|floder_name/i
// selectorBlackList: ['weui','mu']
})
module.exports = {
css: {
loaderOptions: {
postcss: {
plugins: [
px2remConfig
]
}
}
}
}
三,图片添加和1像素边框
dpr2和dpr3屏幕的出现,屏幕分辨率更多,图画更加清晰。但是我们在编写样式时,依然是根据css像素编写的,而非设备物理像素。为了能使设备性能最大化体现,在图片的处理中,一般会针对2倍屏及以下加载2倍图,对3倍屏加载3倍图。采用less mixin来实现媒体查询并加载对应的背景图片。
mixin.less
.bg-image(@url) {
background-image: e(%("url(../assets/%a@2x.png)", e(@url)));
@media (-webkit-min-device-pixel-ratio: 3),
(min-device-pixel-ratio: 3) {
background-image: e(%("url(../assets/%a@3x.png)", e(@url)));
}
}
在需要按分辨率添加背景图片的地方:
@import "../assets/style/mixin.less";
.close {
width: 42px;
height: 42px;
.bg-image('close');
background-position: center;
background-repeat: no-repeat;
background-size: 100% 100%;
}
这个只是背景图片的处理,对于img标签的图片也有简单方法处理,srcset标签可根据屏幕宽度或者像素比来加载对应的图片,如果不是对应的值,就加载默认图片。
<img srcset="foo-375w.jpg,
foo-750w.jpg 2x,
foo-751w.jpg 3x"
src="foo-750w.jpg">
关于1像素边框,在很多UI图中,1像素是指的一个物理像素,而非css像素,如果我们用css像素去开发,在多倍屏上就会显得较粗,遇到较真的UI和产品就会指出来要求一定要修复。所以我们需要采用一些手段来实现1个物理像素的边框,缩放就是很好的手段。
mixin.less
.border-1px(@color: #ccc, @radius: 2PX, @style: solid){
position: relative;
&::after {
content: "";
pointer-events: none;
display: block;
position: absolute;
left: 0;
top: 0;
transform-origin: 0 0;
border: 1PX @style @color;
border-radius: @radius;
box-sizing: border-box;
width: 100%;
height: 100%;
@media (min-resolution: 2dppx){
width: 200%;
height: 200%;
border-radius: @radius * 2;
transform: scale(.5);
}
@media (min-resolution: 3dppx){
width: 300%;
height: 300%;
border-radius: @radius * 3;
transform: scale(.333);
}
}
}
四,添加环境变量
在实际开发中,我们可能会涉及开发环境、预生产环境、生产环境等等,每个环境中会涉及不同的配置,如后台接口地址、发布路由等,为了避免在开发和打包过程中频繁注释和更改这些配置,我们可以把他们写入环境变量配置文件里。在项目根目录下创建.env.xxx
文件,xxx为当前的环境模式,如development production
,对于预发布环境等,我们在打包时定义模式
package.json
"scripts": {
"serve": "vue-cli-service serve",
"build:test": "vue-cli-service build --mode test",
"build:prod": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
采用 npm run build:test
命令打包的项目会自动读取.env.test
文件中配置
.env.test
NODE_ENV = 'production'
# 键名须以VUE_APP开头
VUE_APP_ENV = 'test'
VUE_APP_MODE = 'test'
VUE_APP_SSO='http://localhost:9080'
在需要使用到环境变量的地方,通过process.env.envName
即可读取到配置。
五,webpack额外配置
使用vue-cli创建的项目,其实已经有了相应的简单配置。但是我们依然可以额外配置vue.config.js
,达到webpack性能的最大化
详细的可以参考 https://mp.weixin.qq.com/s/ffUcsTnVNtTb-VinH8Llvg
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。