在通常的前端开发中,咱们通常会利用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"'
复制代码