乐趣区

关于javascript:分享一个Vue项目实践方案

一,创立一个 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

退出移动版