Vue项目实现移动端适配笔记

注意:以下过程是在Vue CLI 2环境下

通过npm命令安装vue-cli

vue init webpack project-name

安装完毕后package.json文件如下

{
  "name": "ceshi",
  "version": "1.0.0",
  "description": "A Vue.js project",
  "author": "huxin ",
  "private": true,
  "scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "build": "node build/build.js"
  },
  "dependencies": {
    "vue": "^2.5.2",
    "vue-router": "^3.0.1"
  },
  "devDependencies": {
    "autoprefixer": "^7.1.2",
    "babel-core": "^6.22.1",
    "babel-helper-vue-jsx-merge-props": "^2.0.3",
    "babel-loader": "^7.1.1",
    "babel-plugin-syntax-jsx": "^6.18.0",
    "babel-plugin-transform-runtime": "^6.22.0",
    "babel-plugin-transform-vue-jsx": "^3.5.0",
    "babel-preset-env": "^1.3.2",
    "babel-preset-stage-2": "^6.22.0",
    "chalk": "^2.0.1",
    "copy-webpack-plugin": "^4.0.1",
    "css-loader": "^0.28.0",
    "extract-text-webpack-plugin": "^3.0.0",
    "file-loader": "^1.1.4",
    "friendly-errors-webpack-plugin": "^1.6.1",
    "html-webpack-plugin": "^2.30.1",
    "node-notifier": "^5.1.2",
    "optimize-css-assets-webpack-plugin": "^3.2.0",
    "ora": "^1.2.0",
    "portfinder": "^1.0.13",
    "postcss-import": "^11.0.0",
    "postcss-loader": "^2.0.8",
    "postcss-url": "^7.2.1",
    "rimraf": "^2.6.0",
    "semver": "^5.3.0",
    "shelljs": "^0.7.6",
    "uglifyjs-webpack-plugin": "^1.1.1",
    "url-loader": "^0.5.8",
    "vue-loader": "^13.3.0",
    "vue-style-loader": "^3.0.1",
    "vue-template-compiler": "^2.5.2",
    "webpack": "^3.6.0",
    "webpack-bundle-analyzer": "^2.9.0",
    "webpack-dev-server": "^2.9.1",
    "webpack-merge": "^4.1.0"
  },
  "engines": {
    "node": ">= 6.0.0",
    "npm": ">= 3.0.0"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ]
}

另外根目录下的一个.postcssrc.js文件,内容如下

// https://github.com/michael-ciniawsky/postcss-load-config

module.exports = {
  "plugins": {
    "postcss-import": {},
    "postcss-url": {},
    // to edit target browsers: use "browserslist" field in package.json
    "autoprefixer": {}
  }
}

从上可见,初始化的vue-cli项目中已经安装了以下三个组件

  • postcss-import
  • postcss-url
  • autoprefixer

然后我们还需要安装以下六个组件

npm i postcss-aspect-ratio-mini postcss-px-to-viewport postcss-write-svg postcss-cssnext postcss-viewport-units cssnano --S
  • postcss-aspect-ratio-mini
  • postcss-px-to-viewport
  • postcss-write-svg
  • postcss-cssnext
  • cssnano
  • postcss-viewport-units
-->-->注意:本文全篇都是以vue-cli2为基础的,vue-cli3中以上介绍的9个组件都是没有提前安装的,所以命令如下:
npm i autoprefixer postcss-url postcss-import postcss-aspect-ratio-mini postcss-px-to-viewport postcss-write-svg postcss-cssnext postcss-viewport-units cssnano --S

安装完毕后,package.json文件如下

{
  "name": "ceshi",
  "version": "1.0.0",
  "description": "A Vue.js project",
  "author": "huxin ",
  "private": true,
  "scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",
    "build": "node build/build.js"
  },
  "dependencies": {
    "cssnano": "^4.1.0",
    "postcss-aspect-ratio-mini": "0.0.2",
    "postcss-cssnext": "^3.1.0",
    "postcss-px-to-viewport": "0.0.3",
    "postcss-viewport-units": "^0.1.4",
    "postcss-write-svg": "^3.0.1",
    "vue": "^2.5.2",
    "vue-router": "^3.0.1"
  },
  "devDependencies": {
    "autoprefixer": "^7.1.2",
    "babel-core": "^6.22.1",
    "babel-helper-vue-jsx-merge-props": "^2.0.3",
    "babel-loader": "^7.1.1",
    "babel-plugin-syntax-jsx": "^6.18.0",
    "babel-plugin-transform-runtime": "^6.22.0",
    "babel-plugin-transform-vue-jsx": "^3.5.0",
    "babel-preset-env": "^1.3.2",
    "babel-preset-stage-2": "^6.22.0",
    "chalk": "^2.0.1",
    "copy-webpack-plugin": "^4.0.1",
    "css-loader": "^0.28.0",
    "extract-text-webpack-plugin": "^3.0.0",
    "file-loader": "^1.1.4",
    "friendly-errors-webpack-plugin": "^1.6.1",
    "html-webpack-plugin": "^2.30.1",
    "node-notifier": "^5.1.2",
    "optimize-css-assets-webpack-plugin": "^3.2.0",
    "ora": "^1.2.0",
    "portfinder": "^1.0.13",
    "postcss-import": "^11.0.0",
    "postcss-loader": "^2.0.8",
    "postcss-url": "^7.2.1",
    "rimraf": "^2.6.0",
    "semver": "^5.3.0",
    "shelljs": "^0.7.6",
    "uglifyjs-webpack-plugin": "^1.1.1",
    "url-loader": "^0.5.8",
    "vue-loader": "^13.3.0",
    "vue-style-loader": "^3.0.1",
    "vue-template-compiler": "^2.5.2",
    "webpack": "^3.6.0",
    "webpack-bundle-analyzer": "^2.9.0",
    "webpack-dev-server": "^2.9.1",
    "webpack-merge": "^4.1.0"
  },
  "engines": {
    "node": ">= 6.0.0",
    "npm": ">= 3.0.0"
  },
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not ie <= 8"
  ]
}

然后按照如下内容配置.postcssrc.js文件(在vue-cli3中,文件名称为postcss.config.js)

module.exports = {
    "plugins": {
        "postcss-import": {},
        "postcss-url": {},
        "postcss-cssnext": {},
        "postcss-px-to-viewport": {
            viewportWidth: 750, // 视窗的宽度,对应的是我们设计稿的宽度,一般是750
            viewportHeight: 1334, // 视窗的高度,根据750设备的宽度来指定,一般指定1334,也可以不配置
            unitPrecision: 3, // 指定`px`转换为视窗单位值的小数位数(很多时候无法整除)
            viewportUnit: 'vw', // 指定需要转换成的视窗单位,建议使用vw
            selectorBlackList: ['.ignore', '.hairlines'], // 指定不转换为视窗单位的类,可以自定义,可以无限添加,建议定义一至两个通用的类名
            minPixelValue: 1, // 小于或等于`1px`不转换为视窗单位,你也可以设置为你想要的值
            mediaQuery: false // 允许在媒体查询中转换`px`
        },
        "postcss-viewport-units": {},
        "cssnano": {
            "cssnano-preset-advanced": {
                zindex: false,
                autoprefixer: false
            }
        }
    }
}

npm run dev运行项目后会报错,如下(在几次vue-cli3的项目中,走到这一步都没有报这个错,所以根据实际情况来确定是否安装下面的组件)

 error  in ./src/App.vue

Module build failed: Error: Cannot load preset "advanced". Please check your configuration for errors and try again.
    at resolvePreset (F:\Net\ceshi\node_modules\cssnano\dist\index.js:83:11)
    at resolveConfig (F:\Net\ceshi\node_modules\cssnano\dist\index.js:94:16)
    at F:\Net\ceshi\node_modules\cssnano\dist\index.js:119:16
    at LazyResult.run (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:277:20)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:192:32)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:204:22)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:204:22)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:204:22)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:204:22)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:204:22)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:204:22)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:204:22)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:204:22)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:204:22)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:204:22)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:204:22)

 @ ./node_modules/vue-style-loader!./node_modules/css-loader?{"sourceMap":true}!./node_modules/vue-loader/lib/style-compiler?{"vue":true,"id":"data-v-7ba5bd90","scoped":false,"hasInlineConfig":false}!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/App.vue 4:14-296 13:3-17:5 14:22-304
 @ ./src/App.vue
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://localhost:8080 webpack/hot/dev-server ./src/main.js

 error  in ./src/components/HelloWorld.vue

Module build failed: Error: Cannot load preset "advanced". Please check your configuration for errors and try again.
    at resolvePreset (F:\Net\ceshi\node_modules\cssnano\dist\index.js:83:11)
    at resolveConfig (F:\Net\ceshi\node_modules\cssnano\dist\index.js:94:16)
    at F:\Net\ceshi\node_modules\cssnano\dist\index.js:119:16
    at LazyResult.run (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:277:20)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:192:32)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:204:22)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:204:22)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:204:22)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:204:22)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:204:22)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:204:22)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:204:22)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:204:22)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:204:22)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:204:22)
    at LazyResult.asyncTick (F:\Net\ceshi\node_modules\postcss\lib\lazy-result.js:204:22)

 @ ./node_modules/vue-style-loader!./node_modules/css-loader?{"sourceMap":true}!./node_modules/vue-loader/lib/style-compiler?{"vue":true,"id":"data-v-469af010","scoped":true,"hasInlineConfig":false}!./node_modules/vue-loader/lib/selector.js?type=styles&index=0!./src/components/HelloWorld.vue 4:14-311 13:3-17:5 14:22-319
 @ ./src/components/HelloWorld.vue
 @ ./src/router/index.js
 @ ./src/main.js
 @ multi (webpack)-dev-server/client?http://localhost:8080 webpack/hot/dev-server ./src/main.js

要解决这个报错,需要安装这个插件

npm i cssnano-preset-advanced --save-dev

按照上面的步骤安装完毕后,基本上项目可以运行了。
以上方法我也是从一篇博客上学来,这里只记录一下安装步骤,以及遇到过的问题。关于使用到的组件的具体介绍可以看原博客https://www.w3cplus.com/mobile/vw-layout-in-vue.html

后续补充

在之后的项目中测试发现,vw这个单位在一些较老版本手机上(安卓4.2之前的版本)不是很友好,如果需要兼容这些老手机的话,可以装viewport-units-buggyfill这个组件,安装完成后在main.js中引用这个组件

npm i viewport-units-buggyfill -S
var hacks = require('viewport-units-buggyfill/viewport-units-buggyfill.hacks');
require('viewport-units-buggyfill').init({
    hacks: hacks
});

此外,在一些老手机中还发现关于es6兼容问题,vue-cli中原本所引用的bable并不能完美解决这个问题,还需要安装这两个组件。

  • babel-polyfill
  • es6-promise
npm i babel-polyfill es6-promise -S

同样在安装后需要在main.js中应用

import "babel-polyfill"
import 'es6-promise/auto'

最后,希望各位大佬发现不对的地方帮我指出来,谢谢

你可能感兴趣的:(Vue项目实现移动端适配笔记)