Vue移動端專案搭建
首先新起一個專案
vue init webpact projectName
解決適配問題
引入 lib-flexible
和 px2rem-loader
,開啟 build
資料夾,編輯 utils.js
exports.cssLoaders = function (options) { options = options || {} var cssLoader = { loader: 'css-loader', options: { minimize: process.env.NODE_ENV === 'production', sourceMap: options.sourceMap } } const px2remLoader = { loader: 'px2rem-loader', options: { remUnit: 37.5//1rem=多少畫素 這裡的設計稿是750px。 } } ... }
main.js引入
import 'lib-flexible'
專案裡使用設計稿標註的px,編譯或者打包後會自動轉化為rem

image
使用less
cnpm i less less-save -S
再編輯 webpack.base.conf
配置 less-loader
module: { rules: [ { test: /\.less$/, loader: 'style-loader!css-loader!less-loader', }, ... ] }
解決移動端點選300ms延遲
cnpm i fastclick -S
main.js
import FastClick from 'fastclick' FastClick.attach(document.body)
頂部進度條
cnpm i nprogress -S
main.js
import NProgress from 'nprogress' //引入自定義css是為了覆蓋掉預設的進度條的顏色 import './assets/css/nprogress.css' NProgress.configure({ easing: 'ease',// 動畫方式 speed: 500,// 遞增進度條的速度 showSpinner: false, // 是否顯示載入ico trickleSpeed: 200, // 自動遞增間隔 minimum: 0.3 // 初始化時的最小百分比 }) router.beforeEach((to, from , next) => { // 每次切換頁面時,呼叫進度條 NProgress.start(); next() }); router.afterEach(() => { // 在即將進入新的頁面元件前,關閉掉進度條 NProgress.done() })
nprogress.css
#nprogress { pointer-events: none; } #nprogress .bar { background: #FE571B; position: fixed; z-index: 1031; top: 0; left: 0; width: 100%; height: 2px; } /* Fancy blur effect */ #nprogress .peg { display: block; position: absolute; right: 0px; width: 100px; height: 100%; box-shadow: 0 0 10px #FE571B, 0 0 5px #FE571B; opacity: 1.0; -webkit-transform: rotate(3deg) translate(0px, -4px); -ms-transform: rotate(3deg) translate(0px, -4px); transform: rotate(3deg) translate(0px, -4px); } /* Remove these to get rid of the spinner */ #nprogress .spinner { display: block; position: fixed; z-index: 1031; top: 15px; right: 15px; } #nprogress .spinner-icon { width: 18px; height: 18px; box-sizing: border-box; border: solid 2px transparent; border-top-color: #FE571B; border-left-color: #FE571B; border-radius: 50%; -webkit-animation: nprogress-spinner 400ms linear infinite; animation: nprogress-spinner 400ms linear infinite; } .nprogress-custom-parent { overflow: hidden; position: relative; } .nprogress-custom-parent #nprogress .spinner, .nprogress-custom-parent #nprogress .bar { position: absolute; } @-webkit-keyframes nprogress-spinner { 0%{ -webkit-transform: rotate(0deg); } 100% { -webkit-transform: rotate(360deg); } } @keyframes nprogress-spinner { 0%{ transform: rotate(0deg); } 100% { transform: rotate(360deg); } }

image
封裝axios請求
cnpm i axios -S
src資料夾下新建http資料夾,並在資料夾內新建api.js
api.js
/* eslint-disable */ import axios from 'axios' import router from 'vue-router' import Cookies from 'js-cookie' /** * 定義請求常量 * TIME_OUT、ERR_OK */ export const TIME_OUT = 5000;// 請求超時時間 export const ERR_OK = true;// 請求成功返回狀態,欄位和後臺統一 // export const baseUrl = process.env.BASE_URL// 引入全域性url,定義在全域性變數process.env中,開發環境為了方便轉發,值為空字串 // 環境的切換 console.log('process.env.NODE_ENV:'+process.env.NODE_ENV); if (process.env.NODE_ENV == 'development') { axios.defaults.baseURL = 'http://api-campus-stg1.pingan.com:8282'; } else if (process.env.NODE_ENV == 'production') { axios.defaults.baseURL = 'http://api-campus.pingan.com'; } // 請求超時時間 axios.defaults.timeout = TIME_OUT // 封裝請求攔截 axios.interceptors.request.use( config => { config.headers['Content-Type'] = 'application/json;charset=UTF-8'; config.headers['accessToken'] = ''; if(Cookies.getJSON('loginMsg')){ config.headers['accessToken'] = Cookies.getJSON('loginMsg').token } return config }, error => { return Promise.reject(error) } ) // 封裝響應攔截,判斷token是否過期 axios.interceptors.response.use( response => { let {data} = response if (data.responseCode === 202) {// 如果後臺返回的錯誤標識為token過期,則重新登入 // token過期移除token localStorage.removeItem('token') // 進行重新登入操作 } else { return Promise.resolve(data) } }, error => { return Promise.reject(error.response) if (error.response.status) { switch (error.response.status) { // 401: 未登入 // 未登入則跳轉登入頁面,並攜帶當前頁面的路徑 // 在登入成功後返回當前頁面,這一步需要在登入頁操作。 case 401: router.replace({ path: '/login', query: { redirect: router.currentRoute.fullPath } }); break; // 403 token過期 // 登入過期對使用者進行提示 // 清除本地token和清空vuex中token物件 // 跳轉登入頁面 case 403: // var toast = Toast.$create({ //txt: '登入過期,請重新登入', //mask: true // }) // toast.show() // 清除token localStorage.removeItem('token'); store.commit('loginSuccess', null); // 跳轉登入頁面,並將要瀏覽的頁面fullPath傳過去,登入成功後跳轉需要訪問的頁面 setTimeout(() => { router.replace({ path: '/login', query: { redirect: router.currentRoute.fullPath } }); }, 1000); break; // 404請求不存在 case 404: // var toast = Toast.$create({ //txt: '網路請求不存在', //mask: true // }) // toast.show() break; // 其他錯誤,直接丟擲錯誤提示 default: // var toast = Toast.$create({ //txt: error.response.data.message, //mask: true // }) // toast.show() } } return Promise.reject(error.response) } ) export default axios
使用方法:
main.js
import axios from './http/api' Vue.prototype.$http = axios
然後就可以在專案中以 this.$http
來進行請求
路由懶載入(增加首屏載入速度)
routes: [ { path: '/', name: 'index', component:resolve=>require(['@/page/index'],resolve) }, ... ]
404頁面
routes: [ { path: '*', name: '404', meta: { title: '404', auth:false,//需要登入 }, component:resolve=>require(['@/page/error'],resolve) } ]
路由鑑權
(1) router/index.js
給每個路由新增一個 auth
欄位來判斷是否需要登入
routes: [ { path: '/', name: 'index', meta: { title: '首頁', auth:true,//需要登入 }, component:resolve=>require(['@/page/index'],resolve) }, ]
main.js
router.beforeEach((to, from , next) => { /* 路由發生變化修改頁面title */ if (to.meta.title) { document.title = to.meta.title } // 每次切換頁面時,呼叫進度條 NProgress.start(); // 對路由進行驗證 if(to.matched.some( m => m.meta.auth)){ if(!store.state.user.isLogin) { // 未登陸 next({path:'/login'}) NProgress.done() }else{ next() } }else{ next() } }); router.afterEach(() => { // 在即將進入新的頁面元件前,關閉掉進度條 NProgress.done() })
其中 store.state.user.isLogin
是vuex裡來判斷使用者登入沒,具體實現方式是登入後儲存 token
等使用者資訊到cookie裡(js-cookie外掛),並設定過期時間為1天(以實際專案為準)然後後面每次請求會帶上 token
,如果後臺返回 token
過期的 code
, commit
並設定 isLogin
為 false
,回到登入頁.(不同專案判斷有所不同,具體以專案為準)
promise相容ie
cnpm i es6-promise -S
main.js
require("es6-promise").polyfill();
引用 vconsole
移動端專案調式怎麼可以少了這個神器.
static
資料夾下新建 vconsole.js
,再去git上拷貝原始碼下來,在 index.html
裡引入, vconsole
地址: ofollow,noindex">點這裡
index.html
<script src="./static/vconsole.js"></script> <script> var vConsole = new VConsole(); </script>
備註:靜態檔案放在 static
還是 assets
是有區別的, static
下的檔案不會被 webpack
處理,任何放在 static/ 中檔案需要以絕對路徑的形式引用,而 assets
會被打包到你的專案裡,正因為這樣,如果 vconsole
放在 assets
檔案下引用,打包後會找不到路徑。一句話總結: static
放別人家的, assets
放自己寫的。
配置開發環境生成環境介面
https://www.jianshu.com/p/1fc65f3f4afa
解決css移動端字母或者文字大小有時會變化的問題
html{ -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; }
谷歌下不支援小於12px,當字型小於12px時 會變成12px 這個時候我們設定的rem及=就沒有效果了 設定text-size-adjust會解決這個問題 禁用Webkit核心瀏覽器的文字大小調整功能
打包後生成很大的.map檔案的問題
在 config/index.js
檔案中,設定 productionSourceMap: false
,就可以不生成.map檔案
檢視打包後各檔案的體積
npm run build --report