基於Vue CLI3 搭建五臟俱全的移動端H5應用

前言

以前開發vue項目,一直是本身搭建腳手架,並無使用配套的Vue-CLI。1、是3.0以前的CLI無明顯優點,配置繁瑣;2、是以爲本身從零配置項目可控性更強。
Vue-CLI 3.0 於去年8月份就已發佈,卻一直沒去了解。近日,有新Vue H5項目開發,就想着用Vue CLI3.0腳手架構建項目。並記錄一下構建使用過程。javascript

使用腳手架最好的參考就是官方文檔,官方文檔總體仍是比較清晰明瞭的,更新也很及時。
連接-官方文檔css

CLI3.0 功能優點

Vue CLI 致力於將 Vue 生態中的工具基礎標準化。它確保了各類構建工具可以基於智能的默認配置便可平穩銜接,這樣你能夠專一在撰寫應用上,而沒必要花好幾天去糾結配置的問題。與此同時,它也爲每一個工具提供了調整配置的靈活性,無需 eject。html

Vue-CLI3.0旨在近一步簡化Vue項目配置,「傻瓜式」配置,促進團隊開發的統一和規範化。同時也徹底能夠是可配置的,保留足夠的擴展性。前端

  • 功能豐富,實現開箱即用,不用再考慮繁瑣的配置。
  • 靈活的插件化機制,加強擴展性。
  • 能夠經過配套的圖形化界面建立、管理項目的配置。有時看着仍是很直觀舒服的。
  • 支持直接將一個vue文件跑起來,進行快速原型開發。
  • 不用過多擔憂配置的更新迭代形成的連帶影響。
  • vue團隊出品,很好地維護並跟進官方的最佳實踐和前沿技術。

image.png

搭建項目

項目git地址:github.com/now1then/vu…vue

初始化項目

安裝腳手架:java

npm install -g @vue/cli
# OR
yarn global add @vue/cli
複製代碼

建立一個項目node

vue create my-project
# OR
vue ui  // 經過圖形化界面建立項目
複製代碼
  • 選擇preset特性(這裏選擇更多功能):

image.png

  • 選擇須要安裝的(Babel、Router、Vuex、Pre-processors、Linter / Formatter):

這裏先不引入TypeScript和單元測試。
    webpack

image.png

  • 路由是否使用history模式(Yes)

image.png

  • 選擇 CSS 預處理器(Less):

image.png

  • 選擇ESLint 配置(ESLint + Standard config)標準配置:

image.png

  • 選擇何時執行ESLint校驗(Lint on save):

image.png

  • 選擇以什麼樣的形式配置以上所選的功能,單獨生成配置文件 or 附加到package.json中(In dedicated config files):

image.png

  • 是否將以前的設置保存爲一個預設模板(y):

image.png

若是選擇 y 後會讓輸入名稱,在下次初始化項目可使用該預設模板快速構建項目。

運行項目

瞭解CLI插件命令ios

啓動開發服務器運行項目:**npm run serve**;
命令會啓動一個開發服務器 (基於 webpack-dev-server) 並附帶開箱即用的模塊熱重載 (Hot-Module-Replacement)。
git

image.png

生產環境打包:npm run build;

圖形化界面

經過 vue ui命令以圖形化界面建立和管理項目:

vue ui
複製代碼

運行成功後,在打開的頁面中能夠新建項目,也能夠導入已有項目。

管理界面:

image.png

目錄介紹:
**項目儀表盤:**自定義展示一些的功能小部件;
**插件:**能夠查看已安裝的CLI插件,還能夠搜索安裝插件;
**依賴:**能夠查看和管理項目的運行依賴和開發依賴;
**配置:**項目的配置項配置管理,包括Vue-CLI配置和ESLint配置等。
**任務:**能夠執行對應任務(對應於package.json中腳本命令),方便查看運行結果和分析檢查。

圖形化界面雖然對於實際開發意義不大,但簡潔直觀,實際體驗仍是不錯的。具體功能最好運行親自體驗。

主流配置插件

Babel

CLI中已預設@vue/cli-plugin-babel,它默認使用 Babel 7 + babel-loader + @vue/babel-preset-app,可是能夠經過 babel.config.js 配置使用任何其它 Babel 預設選項或插件。
『當前僅默認配置就夠用,後續實際使用時逐步增長』

默認會轉換_es6.promise、_``_es6.symbol_等常見ES6語法,對於未引入的語法,採用"顯式地列出了須要的 polyfill的方式"。好比項目中使用es6.string.includes,則設置:

presets: [
    ['@vue/app', {
      'polyfills': [
        'es6.string.includes'
      ]
    }]
  ],
複製代碼

ESLint

@vue/cli-plugin-eslint
『當前僅適用默認配置就夠用。』,具體根據我的習慣和項目規範調整便可。
好比,本人通常關閉如下設置:

rules: {
    'no-console': process.env.NODE_ENV === 'production' ? 'warning' : 'off',
    'no-debugger': process.env.NODE_ENV === 'production' ? 'warning' : 'off',
    'semi': 0, // 語句結尾分號
    'camelcase': 0, //駝峯命名
    'comma-dangle': 0, // 對象最後逗號
    'space-before-function-paren': 0, // 函數定義前,括號前分割
  },
複製代碼

加載mint-ui庫

// 安裝
npm install mint-ui
複製代碼
按需引入

藉助 babel-plugin-component,咱們能夠只引入須要的組件,以達到減少項目體積的目的。
首先,安裝 babel-plugin-component:

npm install babel-plugin-component -D
複製代碼

而後,將babel.config.js 修改成:

module.exports = {
  presets: [
    ['@vue/app', {
      'polyfills': [
        'es6.string.includes'
      ]
    }]
  ],
  "plugins": [
    ["component", {
      "libraryName": "mint-ui",
      "style": true
    }]
  ]
}

複製代碼

這樣使用組件就能夠按需引入了。

ajax請求封裝

藉助Axios庫實現http請求

「連接-axios中文文檔

安裝:
npm install axios;
複製代碼

封裝要達成的目標:

  • 統一維護管理接口;
  • 支持接口代理轉發;
  • 讀取環境配置,區分處理環境。
  • 攔截請求和響應,處理登陸超時、404等異常狀況;
  • 根據請求的配置匹配接口URL前綴且做支持作特殊處理。

具體詳見本人另外一篇文章:
漫漫長路-Axios封裝

移動端適配

考慮瀏覽器兼容性和使用習慣,移動端適配仍是手淘模式,採用px轉remlib-flexible實現。
postcss-pxtorem插件把配置的px轉成rem;
lib-flexible庫則根據頁面尺寸和dpr,自動設置html的字體和meta縮放比例。

  1. 安裝postcss-pxtorem插件
yarn add postcss-pxtorem -D
複製代碼
  1. postcss.config.js中增長pxtorem配置
// postcss.config.js
module.exports = {
  plugins: {
    "autoprefixer": {}, 用來自動處理瀏覽器前綴的一個插件。
    "postcss-
    ": {
      "rootValue": 37.5, // 設計稿寬度的1/10
      "unitPrecision": 5, //小數位
      "minPixelValue": 1, //轉換的最小單位
      "selectorBlackList": [], //忽略的樣式, 正則
      "propList": ["*"] // 須要作轉化處理的屬性,如`hight`、`width`、`margin`等,`*`表示所有,正則
    }
  }
}

複製代碼

根據項目實際狀況靈活配置。

  1. 安裝lib-flexible,並在入口文件main.js中引入
// 安裝 lib-flexible
yarn add lib-flexible

// main.js中引入lib-flexible
import 'lib-flexible';
複製代碼

引入移動端調試工具

手機設備上調試H5很是不方便,這時能夠引入一個很是好用的調試工具Eruda。

Eruda 是一個專爲手機網頁前端設計的調試面板,相似 DevTools 的迷你版,其主要功能包括:捕獲 console 日誌、檢查元素狀態、顯示性能指標、捕獲XHR請求、顯示本地存儲和 Cookie 信息、瀏覽器特性檢測等等。
詳情請訪問-Github連接

能夠經過CDN引用,固然也能夠下載到項目中直接使用。

本項目配置中使用CLI環境變量配置,來設置是否加載Eruda。 實際項目使用可靈活配置。
.env.development文件設置環境變量:

VUE_APP_ERUDA=false  # ture表示啓用Eruda調試工具
複製代碼

index.html文件設置:

<!--手機調試-->
<% if (VUE_APP_ERUDA === 'true') { %>
  <script src="//cdn.bootcss.com/eruda/1.5.2/eruda.min.js"></script>
  <script> window.eruda.init(); </script>
  <% } %>
複製代碼

效果:

ereda演示.gif

其餘CLI配置

postcss.config.js

postcss-import:該插件主要是解決@import引入路徑問題。引入本地文件、node_modules等的文件。
postcss-url:該插件主要用來處理文件,好比圖片文件、字體文件等引用路徑的處理。
autoprefixer:用來自動處理瀏覽器前綴的一個插件。

可視化分析工具

利用可視化資源分析工具插件webpack-bundle-analyzer 分析生產文件打包大小。

// vue.config.js 
configureWebpack: config => {
    // 生產環境打包分析體積
    if (process.env.NODE_ENV === 'production' && process.env.npm_config_report) {
      return {
        plugins: [
          new BundleAnalyzerPlugin()
        ]
      }
    }
  },
複製代碼

終端命令:yarn build --report
固然圖形化界面任務->build->分析 中也能夠粗略分析打包大小。

統一設置less全局變量

參考「連接-Vue-CLI3 css自動導入」。
利用style-resources-loader插件,給Vue單文件自動全局導入配置路徑中的LESS變量和mixin函數。 這樣在使用時不用每一個文件都單獨引入,就能夠直接使用定義的Less變量。

安裝style-resources-loader
yarn add style-resources-loader -D
複製代碼
vue.config.js 配置
chainWebpack: config => {   // CLI內部webpack配置
  const types = ['vue-modules', 'vue', 'normal-modules', 'normal']
  types.forEach(type => addStyleResource(config.module.rule('less').oneOf(type)))
},
// 全局樣式 變量、函數
function addStyleResource (rule) {
  rule.use('style-resource')
    .loader('style-resources-loader')
    .options({
      patterns: [
        path.resolve(__dirname, 'src/styles/variables.less'),
        path.resolve(__dirname, 'src/styles/mixin.less'),
      ],
    })
}
複製代碼

項目其餘改動:

CSS樣式初始化

引入_normalize.css_ 、_minireset.css _+ 自定義CSS設置,初始化CSS樣式,使HTML元素樣式在跨瀏覽器上表現得的高度一致性。
下載對應文件,直接放到src/assets/styles/路徑下。

引入fastclick

移動端點擊有300ms延遲,主要是爲了解決雙擊縮放,瀏覽器等待300ms以判斷是不是雙擊操做。
能夠採用引入fastclick.js的方式解決移動端300ms延遲的問題。固然,fastclick.js曾經在老版本手機上解決移動端300ms的問題上作出了很大的貢獻。時至今日是否還有必要使用,各方仍是各持一詞。

// 安裝
yarn add fastclick

// main.js中引入使用
import FastClick from 'fastclick';
FastClick.attach(document.body);
複製代碼

項目開發

目錄結構

在團隊開發時,規範的目錄拆分約定,有利於協調開發和項目的長期維護。
根據我的習慣及經驗,項目目錄構建以下圖所示:

image.png

項目開發都在src目錄下;

src/assets目錄主要存放靜態資源文件,好比字體圖標、圖片、直接引入的或不常變動的第三方庫等。

Vue模塊說明

全局公共components組件、filter過濾器、directive指令能夠直接注入到全局Vue,也能夠在使用時頁面組件內單獨按需注入。

全局組件分爲:
components_basics公共基礎組件,主要存放封裝的與業務無關的基礎組件。
components_modules公共業務組件,主要存放提取的可重用業務組件。
對於不重用的業務組件,不用提取到外部,直接存放到具體的頁面目錄下便可。

頁面組件內按需引入模塊:

<script>
import { formatDate } from '@/utils/cloud-utils';
import MainButton from '@/component_basics/MainButton';
import transferDom from '@/directives/transferDom';

export default {
  name: 'demoPage',
  components: { // 組件
    MainButton
  },
  directives: { // 指令
    transferDom
  },
  filters: { // 過濾器
    formatDate
  },
  data() {
    return {
      title: '測試'
    }
  },
  methods: {}
}
</script>
複製代碼

Router路由封裝

  1. 路由懶加載

連接-Vue Router懶加載
把組件按組分塊,結合 Vue 的異步組件和 Webpack 的代碼分割功能,實現路由組件的懶加載。

...
const Hello = () => import(/* webpackChunkName: "apply" */ '@/views/hello');
const Demo = () => import(/* webpackChunkName: "demo" */ '@/views/demo');
複製代碼
  1. 路由攔截

經過自定義meta參數,設置路由信息。
利用vue-router導航衛士,路由攔截時,做一些自定義處理。好比登陸權限校驗、頁面標題設置等。

// 部分路由信息
  {
    path: '/demo',
    name: 'demo',
    component: Demo,
    meta: {
      title: '演示Demo', // 標題
      requireAuth: true, // 登陸權限
      keepAlive: false,
    }
  },
    
//路由攔截
// 路由導航守衛
router.beforeEach((to, from, next) => {
  // 登陸權限
  if (to.meta.requireAuth) { // 判斷是否校驗登陸權限
    if (!window.userName) { // 判斷是否登陸,根據實際業務處理
      next({
        path: '/login',
        query: {
          redirect: to.fullPath // 未登陸,跳轉到登陸頁,登陸後跳轉回當前頁。
        }
      })
      return;
    }
  }
  // 路由發生變化修改頁面title
  if (to.meta.title) {
    document.title = to.meta.title + ' | vue-h5-pro';
  } else {
    document.title = 'vue-h5-pro';
  }
  next()
})
複製代碼

頁面平滑切換動畫

效果圖:

頁面切換動畫.gif

這裏實現頁面前進/後退時的整屏平滑左劃/右劃效果。
簡單記錄5個歷史路由,進入新頁面有左劃切換效果,並記錄歷史路由;進入歷史頁面有右劃切換效果,並清除歷史路由。

router.js文件中攔截路由,記錄歷史路由信息。

// 路由攔截 router.js
router.afterEach((to, from) => {
  // console.log(to, from);
  if (!(from.path === '/' && from.name === null)) {
    setLocalRoute(to, from)
  }
});

function setLocalRoute(to, from) {
  // 本地已訪問頁面路由,存5條
  const localRoute = window.myVue.localRoute = window.myVue.localRoute || [];
  const from_index = localRoute.indexOf(from.path);
  const to_index = localRoute.indexOf(to.path);
  if (from_index < 0) {
    localRoute.unshift(from.path);
    to_index >= 0 && localRoute.splice(to_index, 1)
  }
  if (localRoute.length > 5) {
    localRoute.splice(0, 1)
  }
}
複製代碼

main.vue文件中根據路由跳轉,動態設置過渡動畫樣式。

<template>
  <div id="app">
    <transition :name="direction">
      <router-view class="page" />
    </transition>
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {};
  },
  computed: {
    // 動態設置過渡樣式
    direction: function() {
      const currentPath = this.$route.path;
      const localRoute = (window.myVue && window.myVue.localRoute) || [];
      // console.log(localRoute, currentPath);
      const index = localRoute.indexOf(currentPath);
      let tranName = '';

      if (localRoute.length === 0) {
        tranName = 'fade'; // 首頁,漸顯
      } else if (index >= 0) {
        tranName = 'page-back'; // 回退,右劃
      } else {
        tranName = 'page-go'; // 進入新頁面,左劃
      }
      return tranName;
    }
  },
};
</script>

<style lang="less">
  .page {
    position: absolute;
    width: 100%;
    height: 100%;
    transition: all 0.8s ease-in-out;
  }
  .page-go-enter-active {
    transform: translate3d(100%, 0, 0);
  }
  .page-go-enter-to {
    transform: translate3d(0, 0, 0);
  }
  .page-go-leave-active {
    transform: translate3d(0, 0, 0);
  }
  .page-go-leave-to {
    transform: translate3d(-100%, 0, 0);
  }
  .page-back-enter-active {
    transform: translate3d(-100%, 0, 0);
  }
  .page-back-enter-to {
    transform: translate3d(0, 0, 0);
  }
  .page-back-leave-active {
    transform: translate3d(0, 0, 0);
  }
  .page-back-leave-to {
    transform: translate3d(100%, 0, 0);
  }
}
</style>

複製代碼

項目構建及開發細節後續會持續更新。具體的代碼歡迎訪問項目查看。

通用化組件(更新...)

此處記錄封裝的通用化基礎組件。
通用化基礎組件存放於src/component_basic/目錄下。

Tip提示組件

好比:tip提示組件,組件使用及代碼詳見項目。
效果圖:

點擊tip.gif

項目連接

Github連接:github.com/now1then/vu…
Vue-CLI3搭建移動端H5應用-語雀:www.yuque.com/nowthen/lon…
Vue-CLI3搭建移動端H5應用-掘金:juejin.im/post/5d674d…

待完善點:

  • 制定代碼及命名規範

  • 項目打包上傳配置

  • 完善通用化組件

  • 引入mock平臺

  • 國際化語言配置

  • 提取單獨的PC端項目配置

  • 考慮支持多頁

相關文章
相關標籤/搜索