寫這個配置的目的主要是 滿足多baseURL請求需求,不喜歡使用 fly- get post那套 不可能傻乎乎的 每個 baseURL寫一個 fly-get post;
我的項目位址https://gitee.com/ming34902/mpvue-quick-test1.git 放碼雲了,沒有放github
基于mpvue官方mpvue-quickstart 項目模闆,配置fly+vuex+easymock實作多baseURL請求配置,token攔截登入等功能,主要是友善 自己 後續 要是老闆要求用坑爹 mpvue 寫微信小程式 準備,本來用原生寫的挺好的;
一、 準備工作
1. 下載下傳mpvue官方mpvue-quickstart 項目模闆,
http://mpvue.com/mpvue/quickstart/ 根據官方指引 自行安裝 mpvue-quickstart 項目模闆;
吐槽:官方mpvue2.0 之前版本 出現依賴報錯問題,清空依賴 重新 npm install 都無法解決 百思不得其解,百度都找不出來,後面去github看mpvue的issues上才發現這問題是最近 mpvue更新出現 依賴bug報錯,導緻之前建立的幾個mpvue初始項目模闆丢棄,用mpvue2.0版本 以及mpvue-quickstart項目模闆為基礎 重新二次 配置自己想要的(fly多host請求,token攔截) 初始化的項目模闆 ;
上述問題,mpvue2.0版本以下的項目 運作npm run dev(官方依賴問題)報錯:
[mpvue-loader] need "fileExt" option in file "build/vue-loader.conf.js"
Module build failed: Error: [mpvue-loader] need "fileExt" option in file "build/vue-loader.conf.js",init a new project and copy the directory "build/" to this porject, or just check the "fileExt" option
解決:使用mpvue2.0版本 以及mpvue-quickstart項目模闆,重新寫呗;
其他mpvue問題 就不多吐槽了,反正滿頭包.....
2. HTTP 請求終極解決方案flyio ,有些類似axios
https://wendux.github.io/dist/#/doc/flyio/readme flyio官方文檔
3. easyMock 線上mock平台
就是不用寫背景,直接自己創個項目 寫接口配置(api+method+json)模拟背景api請求 傳回資料,非常友善;
https://easy-mock.com
二、開始配置檔案
假設你已準備好 mpvue-quickstart 項目模闆檔案,以及 微信web開發工具 appid 、easymock等;
1. 環境配置 config目錄dev.env.js
var merge = require('webpack-merge')
var prodEnv = require('./prod.env')
module.exports = merge(prodEnv, {
NODE_ENV: '"development"',
// BASE_API: '"https://ao-api-test.xxx.com"',
BASE_API_UAA: '"https://easy-mock.com/mock/xxxx1/lisa-uaa"', // 單點登入
BASE_API: '"https://easy-mock.com/mock/xxx8/lisa-mpvue-test1"', // 提供正常業務需求
})
2. flyio 寫request.js 寫請求,加了白名單、token攔截檢查登入
import Fly from 'flyio/dist/npm/wx';
// import Fly from 'flyio' // 引用失敗
// 擷取白名單
import whiteList from '@/utils/whiteList';
const fly = new Fly();
//設定逾時
fly.config.timeout = 20000;
// const Authorization = wx.getStorageSync('Authorization');
//添加請求攔截器
fly.interceptors.request.use((request) => {
console.log('request', request);
// 不顯示加載頁面的接口
if (whiteList.loading.indexOf(request.url) === -1) {
// 隐藏loading遮罩
}
wx.showLoading({
'title': '加載中',
'mask': true
});
// 請求資源伺服器時,不添加token
if (whiteList.nullHeaderToken.indexOf(request.url) !== -1) {
request.timeout = 30000; // 請求逾時
request.headers = {
'content-type': 'application/json',
'X-Tag': 'flyio'
};
return request;
}
const Authorization = wx.getStorageSync('Authorization');
// 延遲發請求 等 getStorageSync 存儲
setTimeout(() => {
// 無token 則跳轉登陸頁
if (Authorization) {
// 給所有請求添加自定義header
request.timeout = 30000;
request.headers = {
'content-type': 'application/json',
'X-Tag': 'flyio',
'Authorization': 'Bearer ' + Authorization
};
} else {
// promise.reject(request)
console.log('沒有token跳轉登入');
setTimeout(() => {
wx.redirectTo({
url: '/pages/login/main'
});
}, 300)
}
return request;
}, 300)
}, (error,promise) => {
// Do something with request error
console.log(error); // for debug
promise.reject(error)
});
//添加響應攔截器,響應攔截器會在then/catch處理之前執行
fly.interceptors.response.use(
(response) => {
wx.hideLoading();
console.log('interceptors資料', response.data);
//隻将請求結果的data字段傳回
return response.data
},
(err, promise) => {
wx.hideLoading();
let msg = '';
if (err.status === 0) {
msg = '網絡連接配接異常'
} else if (err.status === 1) {
msg = '網絡連接配接逾時'
} else if (err.status === 401) {
msg = '使用者未登入'
} else {
if (err.response.data.message) {
msg = err.response.data.message
} else {
msg = '請求資料失敗,請稍後再試'
}
}
wx.showToast({
title: msg,
icon: 'none',
duration: 2000
});
return promise.resolve(err)
}
);
// Vue.prototype.$http=fly //将fly執行個體挂在vue原型上
export default fly
3. baseURLConfig.js
/**
* 定義目前環境的各個API的 baseURL
*/
const baseURL = {
'NORMAL': process.env.BASE_API,
'UAA': process.env.BASE_API_UAA
};
export default baseURL;
4.業務api 多baseURL,api目錄home.js
import fly from '@/utils/request'
import baseURL from '@/utils/baseURLConfig'
import qs from 'qs'
export function userLogin(data) {
return fly.request({
baseURL: baseURL.UAA, // 使用 BASE_API_UAA
url: '/oauth/token',
method: 'post',
data: qs.stringify(data)
})
}
export function getHomeList(data) {
return fly.request({
baseURL: baseURL.NORMAL, // 使用 BASE_API
url: '/home/index',
method: 'post',
data: qs.stringify(data)
})
}
5.正常使用- index.vue 首頁
import * as HomeApi from '@/api/home'
export default {
....
methods: {
getData() {
const toParams = { id: 1 } // 請求參數
HomeApi.getHomeList(toParams).then((res) => {
console.log('getHomeList()', res.data)
}).catch((error) => { console.log(error) })
},
}
}
6. vuex -action調用
store目錄user.js
import { userLogin } from '@/api/user'
const user = {
state: {
token: '',
name: '',
openId: '初始openId',
userInfo: {}
},
mutations: {
SET_TOKEN: (state, token) => {
state.token = token;
wx.setStorageSync('Authorization', token);
},
SET_OPEN_ID: (state, openId) => {
state.openId = openId;
wx.setStorageSync('openId', openId);
},
SET_NAME: (state, name) => {
state.name = name
},
SET_USER_INFO: (state, userInfo) => {
state.userInfo = userInfo
}
},
actions: {
// 登入
async Login({ commit }, userInfo) {
// 方法一 async+await 成功
const res_data = await userLogin(userInfo)
commit('SET_TOKEN', res_data.data.access_token)
commit('SET_OPEN_ID', res_data.data.openId)
// 登入成功 跳轉首頁
wx.switchTab({
url: '/pages/index/main'
});
}
}
}
export default user
具體使用login.vue
import { mapActions } from 'vuex'
export default {
....
methods: {
...mapActions('user', [
'Login'
]),
async doLogin() {
const that = this
const check_res = that.checkLoginParams()
if (check_res) {
wx.showLoading({
title: '登入中...', //提示的内容,
mask: true, //顯示透明蒙層,防止觸摸穿透,
success: (res) => { console.log(res) }
});
// 擷取微信賬号登入時的code
let resCode = wx.getStorageSync('resCode')
const params = {
'code': resCode,
'username': that.usernameInput,
'password': that.pwdInput
}
await that.Login(params)
}
},
// 賬号 和 密碼 校檢
checkLoginParams: function() {
const that = this
let {usernameInput, pwdInput} = that._data
if (usernameInput === '') {
wx.showToast({
title: '請填寫賬号',
icon: 'none',
duration: 1500
})
return
}
if (pwdInput === '') {
wx.showToast({
title: '請填寫密碼',
icon: 'none',
duration: 1500
})
return
}
return true
}
}
....
}
三、檔案目錄結構注釋md
|-- 項目
|-- .babelrc # 內建es6環境
|-- .editorconfig # 編輯器的配置
|-- .eslintignore # 表示忽略文法檢查的目錄檔案
|-- .eslintrc.js # eslint 嚴格代碼規範
|-- .gitignore # 表示檔案内寫好的檔案路徑都會被Git忽略,不會被送出到代碼倉庫
|-- .postcssrc.js # 對css字首的一些解析
|-- index.html # 入口頁面
|-- package.json # npm包配置檔案,裡面定義了項目的npm腳本,依賴包等資訊
|-- README.md # 項目介紹
|-- build # 腳本目錄
| |-- build.js # 生産環境建構腳本
| |-- check-versions.js # 運作本地建構伺服器,可以通路建構後的頁面
| |-- dev-client.js # 開發伺服器熱重載腳本,主要用來實作開發階段的頁面自動重新整理
| |-- dev-server.js # 運作本地開發伺服器
| |-- utils.js # 建構相關工具方法
| |-- vue-loader.conf.js # vue墊片配置
| |-- webpack.base.conf.js # webpack配置檔案
| |-- webpack.dev.conf.js # webpack開發環境配置
| |-- webpack.prod.conf.js # webpack生産環境配置
|-- config # 項目配置
| |-- dev.env.js # dev開發環境
| |-- index.js # 項目配置檔案
| |-- prod.env.js # prod生産環境
|-- dist # bulid 建構成功後 生産的目錄
|-- src # 開發目錄
| |-- app.json # 路由、tab等配置
| |-- App.vue # 根元件
| |-- main.js # 預編譯入口檔案
| |-- api # api接口目錄
| | |-- home.js
| | |-- user.js
| |-- components # 公共元件目錄
| | |-- card.vue
| |-- pages # 頁面目錄
| | |-- index # 首頁
| | | |-- index.vue
| | | |-- main.js
| | | |-- style.scss
| | |-- login # 登入頁
| | | |-- login.vue
| | | |-- main.js
| | | |-- style.scss
| | |-- logs # 登入日志頁
| | | |-- index.vue
| | | |-- main.js
| | | |-- main.json
| | |-- search # 搜尋頁
| | |-- index.vue
| | |-- main.js
| | |-- style.scss
| |-- store # vuex目錄
| | |-- index.js # vuex 注冊
| | |-- modules # 業務子產品
| | |-- home.js
| | |-- user.js
| |-- style # 樣式目錄
| | |-- common.css
| | |-- index.css
| | |-- weui.css
| |-- utils # 工具目錄
| |-- baseURLConfig.js # baseURL配置
| |-- global.js # 全局資料存儲 global
| |-- index.js #
| |-- request.js # fly 請求
| |-- wechat.js # wechat微信原生api
| |-- whiteList.js # 請求白名單
| |-- common # 公共類
| | |-- mixins.js
| | |-- tips.js
| | |-- utils.js
| |-- lib # 圖書館
| |-- amap-wx.js # 高德-wx
|-- static # web靜态資源加載目錄 不會被wabpack建構
|-- images
|-- common
|-- tabs