在通常的前端開發中,咱們通常會利用mock產生數據來過渡到正式api實現之間的真空期,當正式api實現後,再把mock地址切換爲正式api地址。前端
本文就是利用ES7的裝飾器來實現mock和api地址之間的切換。vue
...
async login (params) {
await Api.member.login(params)
}
...
複製代碼
import axios from 'axios'
...
// mock api地址,正式api實現以後,將其刪除便可
@Mock({
method: 'post',
url: '/members/login'
})
async login (params) {
await axios.post('/members/login', params) #正式api地址
}
...
複製代碼
/mock
import axios from 'axios'
axios.defaults.baseURL = '/mock'
/** * mock裝飾器類的初步實現,未作優化判斷 */
function Mock (params) {
const {method, url} = params
return function (target, name, descriptor) {
descriptor.value = async function () {
const result = await axios({
method,
url,
params: arguments[0]
})
return result
}
return descriptor
}
}
export default Mock
複製代碼
/mock
開頭的地址代理到mock服務器proxyTable: {
'/mock':{
target:'http://mock.server.url',
changeOrigin: true,
pathRewrite: {
'^/mock': '/api'
}
},
},
複製代碼
"babel-plugin-transform-decorators-legacy": "^1.3.4",
複製代碼
通過一晚的反覆思考,發現上述實現存在一些問題webpack
因此,針對上述問題作了一些優化。ios
// 增長屬性
constructor () {
this.baseUrl = '/members'
}
// 修改成
@Mock()
async login (params) {
await axios.post(`${this.baseUrl}/login`, params) #正式api地址
}
複製代碼
return function (target, name, descriptor) {
// 初始化目標實例
const targetInstance = new target.constructor()
//根據環境變量判斷並修改實例的baseUrl
targetInstance.baseUrl = process.env.ENABLE_MOCK === 'true'
? `${process.env.MOCK_URL}${targetInstance.baseUrl}`
: targetInstance.baseUrl
const oldValue = descriptor.value
// 目標方法
descriptor.value = async function () {
// 執行原方法
const result = await oldValue.apply(targetInstance, arguments)
return result
}
// 返回
return descriptor
}
複製代碼
// 增長mock配置
ENABLE_MOCK: '"true"',
MOCK_URL: '"/mock"'
複製代碼