今天正好有機會, 整理一下如何新建一個 vue 移動端模板框架
vue create vue_h5
回車
Vue CLI v4.1.1
? Please pick a preset:
ee (router, vuex, babel)
單元測試 (node-sass, babel, router, vuex, eslint, unit-jest)
標準項目 (node-sass, babel, router, vuex, eslint)
default (babel, eslint)
> Manually select features
回車
? Please pick a preset: Manually select features
? Check the features needed for your project:
(*) Babel
( ) TypeScript
(*) Progressive Web App (PWA) Support
(*) Router
(*) Vuex
>(*) CSS Pre-processors
(*) Linter / Formatter
( ) Unit Testing
( ) E2E Testing
以上是我新建選擇的組件
移動端項目 最爲關鍵的就是 px => rem 單位轉換問題
引入Vant UI框架
-
cnpm install vant -S 引入 babel-plugin-import
-
配置按需加載 需要修改 babel.config.js main.js 這兩個文件
-- babel.config.js module.exports = { presets: [ '@vue/app' ], plugins: [ ['import', { libraryName: 'vant', libraryDirectory: 'es', style: true }, 'vant'] ] } -- main.js import { Button, NavBar, Cell } from 'vant' import 'vant/lib/button/style' Vue.use(Button).use(Cell).use(NavBar)
-
統一單位 px -> rem 需要用到 postcss-pxtorem lib-flexible (這裏方案很多,就不多說了)
cnpm isntall lib-flexible -S
cnpm install postcss-pxtorem -D
main.js引入 import ‘lib-flexible/flexible’
之後配置一下 vue.config.js (默認項目是沒有的,自己新建在根目錄 )/** * 配置參考: https://cli.vuejs.org/zh/config/ */ module.exports = { publicPath: process.env.NODE_ENV === 'production' ? './' : '/', productionSourceMap: false, devServer: { open: true, port: 8017, proxy: { '/api': { target: 'http://apitest.oucnet.com', secure: false, ws: true, changeOrigin: true, pathRewrite: { '^/api': '' } } }, overlay: { errors: true, warnings: true } }, css: { loaderOptions: { postcss: { plugins: [ require('postcss-pxtorem')({ rootValue: 37.5, // 換算的基數 propList: ['*'] }) ] } } } }
注: 這裏 publicPath 可能你用的是 vue-cli3 這個參數名稱應該是 baseUrl 我這裏是
vue-cli4.1.1, 我這裏的換算值是 37.5 對應的設計稿是 375 寬的 但是我們一般拿到的設計稿是 750寬的
所以你要調整一下。
這裏調整方式我給我兩種方案
第一種 修改設計稿寬度 我這裏使用的藍湖
第二種 就是修改 postcss-pxtorem 轉換規則 還是按750px 做
vue.config.js 需要改一下 不轉換 vant 組件
css: {
loaderOptions: {
postcss: {
plugins: [
require('postcss-pxtorem')({
rootValue: 75, // 換算的基數
propList: ['*'],
selectorBlackList: ['.van-']
})
]
}
}
}
最終效果
重要組件修改
- router/index.js 修改
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
const routes = [
{
path: '*',
component: () => import('@/views/pages/404'),
name: '404',
meta: { title: '404未找到' }
},
{ path: '/', name: 'index', component: () => import('@/views/index'), meta: { title: '加載中···' } }
]
const router = new Router({
mode: 'history',
scrollBehavior: () => ({ y: 0 }),
base: process.env.BASE_URL,
routes
})
// 攔截器
router.beforeEach((to, from, next) => {
// 動態標題
window.document.title = to.meta.title
// 處理業務問題...
next()
})
// 處理Router的BUG 當前顯示的路由再次點擊會打印錯誤
const originalPush = Router.prototype.push
Router.prototype.push = function push (location) {
return originalPush.call(this, location).catch(err => err)
}
export default router
- axios 以及vuex 的配置 引入兩個組件 cnpm install lodash axios -S
store/index.js 修改
import Vue from 'vue'
import Vuex from 'vuex'
import cloneDeep from 'lodash/cloneDeep'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
},
mutations: {
// 重置vuex本地儲存狀態
resetStore (state) {
Object.keys(state).forEach((key) => {
state[key] = cloneDeep(window.SITE_CONFIG['storeState'][key])
})
}
},
actions: {
},
modules: {
}
})
axios 配置 我這裏在新建了 src/utils/request.js
import axios from 'axios'
import router from '@/router'
import { clearLoginInfo } from '@/utils'
import { Toast } from 'vant'
const http = axios.create({
baseURL: window.SITE_CONFIG['apiURL'],
timeout: 1000 * 180,
withCredentials: true
})
/**
* 請求攔截
*/
http.interceptors.request.use(config => {
return config
}, error => {
return Promise.reject(error)
})
/**
* 響應攔截
*/
http.interceptors.response.use(response => {
if (response.data.code === 401) {
clearLoginInfo()
router.replace({ name: 'login' })
return Promise.reject(response.data.msg)
}
return response
}, err => {
if (err && err.response) {
switch (err.response.status) {
case 301: err.message = '請求的數據具有新的位置且更改是永久的'; break
case 302: err.message = '請求的數據臨時具有不同 URI'; break
case 304: err.message = '未按預期修改文檔'; break
case 305: err.message = '必須通過代理來訪問請求的資源'; break
case 400: err.message = '請求中有語法問題,或不能滿足請求'; break
case 402: err.message = '所使用的模塊需要付費使用'; break
case 403: err.message = '當前操作沒有權限'; break
case 404: err.message = '服務器找不到給定的資源'; break
case 407: err.message = '客戶機首先必須使用代理認證自身'; break
case 415: err.message = '請求類型不支持,服務器拒絕服務'; break
case 417: err.message = '未綁定登錄賬號,請使用密碼登錄後綁定'; break
case 426: err.message = '用戶名不存在或密碼錯誤'; break
case 429: err.message = '請求過於頻繁'; break
case 500: err.message = '服務器內部錯誤,無法完成請求'; break
case 501: err.message = '服務不支持請求'; break
case 502: err.message = '網絡錯誤,服務器接收到上上游服務器無效響應'; break
case 503: err.message = '服務器無法處理請求'; break
case 504: err.message = '網絡請求超時'; break
case 999: err.message = '系統未知錯誤,請反饋給管理員'; break
}
} else {
err.message = '連接服務器失敗!'
}
Toast(err.message)
return Promise.reject(err)
})
export default http
main.js 配置
import Vue from 'vue'
import App from './App.vue'
import './registerServiceWorker'
import router from './router'
import store from './store'
import { Button, NavBar, Cell } from 'vant'
import 'vant/lib/button/style'
import 'lib-flexible/flexible'
import cloneDeep from 'lodash/cloneDeep'
import http from '@/utils/request'
Vue.config.productionTip = false
Vue.use(Button).use(Cell).use(NavBar)
// 掛載全局
Vue.prototype.$http = http
// 保存整站vuex本地儲存初始狀態
window.SITE_CONFIG['storeState'] = cloneDeep(store.state)
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
配置 本地開發域名 上線上線打包域名 需要修改 index.html 和 package.json
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, viewport-fit=cover">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>H5項目模板</title>
<!-- 站點配置 -->
<script>
window.SITE_CONFIG = {};
window.SITE_CONFIG['nodeEnv'] = '<%= process.env.VUE_APP_NODE_ENV %>';
window.SITE_CONFIG['apiURL'] = ''; // api請求地址
window.SITE_CONFIG['storeState'] = {}; // vuex本地儲存初始化狀態(用於不刷新頁面的情況下,也能重置初始化項目中所有狀態)
</script>
<!-- 本地測試環境 -->
<% if (process.env.VUE_APP_NODE_ENV === 'dev') { %>
<script>window.SITE_CONFIG['apiURL'] = '/api';</script>
<% } %>
<!-- 集成上線環境 -->
<% if (process.env.VUE_APP_NODE_ENV === 'prod:sit') { %>
<script>window.SITE_CONFIG['apiURL'] = 'http://127.0.0.1:1000';</script>
<% } %>
</head>
<body>
<noscript>
<strong>We're sorry but 05_h5 doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build --mode development",
"build:sit": "vue-cli-service build --mode production.sit",
"lint": "vue-cli-service lint"
},
最後打包本地測試頁面 cnpm run build
打包上線頁面 cnpm run build:sit