公司讓做兩個(gè)移動(dòng)端頁(yè)面,挺簡(jiǎn)單,但是以前沒(méi)有做過(guò),一切都是摸索著來(lái)。以此紀(jì)念并記錄第一次完整移動(dòng)端開(kāi)發(fā)。
選型
首先決定用vue,UI 框架開(kāi)始的時(shí)候用的 mint-ui,后面感覺(jué)不好看,又調(diào)研了下,用了有贊的 vant。
搭建項(xiàng)目
用 vue-cli3 搭建。
vue-cli3 安裝
如果以前安裝了 vue-cli2,先把它全局卸載了。(要用 vue-cli3,如果以前安裝了 vue-cli x 都需要卸載再安裝 vue-cli3)
npm uninstall vue-cli -g
vue-cli3 需要 nodejs≥ 8.9 (官方推薦 8.11.0+
查看 node 版本號(hào):
node -v
如果 nodejs 版本號(hào)過(guò)低,windows 下需要重新下載 node 安裝包安裝。
安裝 @vue/cli (vue-cli3 的包名由 vue-cli 改為了 @vue/cli):
npm install -g @vue/cli //我在 git bash 下輸入安裝命令,久久沒(méi)有反應(yīng),后面在 cmd 下輸入命令才安裝成功。
查看 vue-cli 版本:
vue -V
vue-cli3 創(chuàng)建項(xiàng)目
vue create <Project Name> //文件名 不支持駝峰(含大寫(xiě)字母)
輸入創(chuàng)建命令后,緊接著是各種配置選擇:手動(dòng)配置,根據(jù)你需要用方向鍵選擇(按 “空格鍵”選擇/取消選擇,A鍵全選/取消全選)對(duì)應(yīng)功能。
安裝完成
npm run serve // 啟動(dòng)項(xiàng)目
至此,項(xiàng)目已搭建完成。
開(kāi)發(fā)依賴(lài)配置
選定 UI 框架是 vant,靜態(tài)文件用 less,移動(dòng)端 rem 適配用 postcss-px2rem-exclude, 分別安裝依賴(lài):
npm i vant -S
npm i less-loader -D
npm i postcss-px2rem-exclude -S
剛開(kāi)始 rem 適配用的 px2rem ,但是會(huì)把 UI 組件里面的 px 也一起轉(zhuǎn)了(UI 組件做了適配處理,不用轉(zhuǎn))。找到了 postcss-px2rem-exclude。安裝了 px2rem 的話,需要卸載再裝 postcss-px2rem-exclude。
npm install postcss-px2rem-exclude -S
配置 postcss-px2rem-exclude
在項(xiàng)目根目錄 (src)下,新建 postcss.config.js 文件:
module.exports = {
"plugins": {
"autoprefixer": {},
"postcss-px2rem-exclude":{
"remUnit": 75, // 根大小 750px = 750/75 = 10 rem
"exclude":/node_modules/i //忽略 node_modules 目錄下的所有文件
}
}
}
動(dòng)態(tài)生成根元素大小, 在 main.js 里面加入
window.onresize = setHtmlFontSize
function setHtmlFontSize () {
const htmlWidth = document.documentElement.clientWidth || document.body.clientWidth
const htmlDom = document.getElementsByTagName('html')[0]
htmlDom.style.fontSize = htmlWidth / 10 + 'px'
}
setHtmlFontSize()
其他配置(跨域配置等)
vue-cli3 創(chuàng)建的項(xiàng)目中,內(nèi)置了 webpack 相關(guān)配置,所以沒(méi)有了 webpack 配置文件,需要修改 webpack 配置的時(shí)候,在根目錄下新建 vue.config.js。以下是我的配置:
module.exports = {
publicPath: 'xxx', // 根路徑
devServer: {
disableHostCheck: true, // 項(xiàng)目中沒(méi)有用到 socket,@vue/cli3 報(bào) socket 連接錯(cuò)誤,關(guān)閉 host 檢查。
overlay:{ // 禁用 eslint 檢查
warnings: false,
errors: false
},
proxy: { // 代理
'/api': {
target: 'http://www.example.com/xx', // 代理的目標(biāo)地址 也可是 http://www.example.com
changeOrigin: true, //開(kāi)啟代理:在本地會(huì)創(chuàng)建一個(gè)虛擬服務(wù)端,然后發(fā)送請(qǐng)求的數(shù)據(jù),并同時(shí)接收請(qǐng)求的數(shù)據(jù),這樣服務(wù)端和服務(wù)端進(jìn)行數(shù)據(jù)的交互就不會(huì)有跨域問(wèn)題
ws: false, // 是否開(kāi)啟 socket
pathRewrite: { // 重定向
'^/api': ' ' // 這種接口配置出來(lái) /api/login ==> http://www.example/xx/login
// '^/api': '/api' 這種接口配置出來(lái) /api/login ==> http://www.example/xx/api/login
// 我的理解是使用時(shí)候 api 代表的地址 = target + '^/api' 對(duì)應(yīng)的 value
}
}
},
},
lintOnSave: false
}
main.js 相關(guān)
axios 配置,安裝 axios
npm i axios -S
main.js 中引入 axios 并設(shè)置攔截器,將其掛載到 vue 實(shí)例上。
import axios from 'axios'
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
// 攔截器設(shè)置
axios.interceptors.request.use((config) => {
if(store.getters.getToken){ // 統(tǒng)一在 header 中加入 token 參數(shù)
config.headers[tokenKey] = getToken();
}
return config
},(error) =>{
return Promise.reject(error)
})
axios.interceptors.response.use((res) => {
return res.data // 返回?cái)?shù)據(jù)
},(error) =>{
return Promise.reject(error)
})
// 掛載實(shí)例
Vue.prototype.$http = axios
main.js 中引入 vant, mixin, router
// vant
import Vant from 'vant'
import 'vant/lib/index.css';
import mixin from '@/mixins/common'
import router from './router'
Vue.use(Vant)
Vue.mixin(mixin)
router.beforeEach((to, from, next) => { // 動(dòng)態(tài)配置每個(gè)頁(yè)面title
if(to.meta.title){
document.title = to.meta.title
}
next();
})
new Vue({
router,
render: h => h(App),
}).$mount('#app')
開(kāi)始開(kāi)發(fā)
配置好后的目錄結(jié)構(gòu):

頁(yè)面放在 views 中,assets 放靜態(tài)文件, utils 里面是一些工具類(lèi)。vue-cli3 中只有一個(gè) store.js 文件。
安裝 vuex :
npm i vuex -S
store.js :
import Vue from 'vue'
import Vuex from 'vuex'
import { getToken } from './utils/auth'
Vue.use(Vuex)
export default new Vuex.Store({
state: { // 相當(dāng)于存儲(chǔ)的變量聲明, 類(lèi)似 vue 文件中的 data,外部文件使用 state 中的變量 store.state.xxx
token: getToken(),
},
mutations: { // 修改變量,外部通過(guò) mutations 改變值 commit('setToken', 'xxx')
setToken(state, token){
state.token = token
}
},
actions: {
},
getters: { // 取值 外部訪問(wèn) store.getters.getToken
getToken(state){
return state.token;
}
}
})
然后哼唧哼唧寫(xiě)頁(yè)面,配路由。
.......當(dāng)當(dāng)當(dāng)當(dāng),開(kāi)發(fā)完畢,大功告成。