框架目的
减低不同业务接口代码的耦合性,减少编写的代码量,方便后续的维护和功能的扩展
框架结构
框架在vue项目中的位置如下:
框架文件结构如下:
相关文件和文件夹的含义:
- module: 里面包含vue项目所需的所有后台业务数据接口的代码,其下的
文件夹`alarm`、`amount`、和`auth`等文件夹均表示一个业务数据模块;
- utils:包含一些功能函数的封装;
- index.js:框架功能的入口,在main.js中使用才可以使业务数据接口生效。
框架相关源码
- index.js
import Axios from 'axios'
// axios设置***
export const axios = Axios.create({
baseURL: 'http://' + window.location.hostname + ':' + window.location.port,
timeout: 5000
})
export const axios_pure = Axios.create({
baseURL: '',
timeout: 5000
})
// ***
import Mock from 'mockjs'
import { XHR2ExpressReqWrap } from './utils/mock_utils'
// Mock设置***
Mock.setup({
timeout: 400
})
export function gu_mock_init() {
// 自动注册业务mock
console.log('******自动mock开始******')
const api_mocks = []
const module_mock = require.context('./module', true, /mock\.js$/)
module_mock.keys().forEach(key => {
console.log('模块 ' + key.match(/\.\/(\S*)\/mock\.js/)[1] + ' 加载成功')
const api_list = module_mock(key).default || module_mock(key)
api_mocks.push(...api_list)
})
console.log('******自动mock结束******')
for (const api_mock of api_mocks) {
Mock.mock(new RegExp(api_mock.url), api_mock.type, XHR2ExpressReqWrap(api_mock.response))
}
}
- ex_utils.js
/**
* 反序列化url
* @param url
* @returns 对象
*/
export function param2Obj(url) {
const search = decodeURIComponent(url.split('?')[1]).replace(/\+/g, ' ')
if (!search) {
return {}
}
const obj = {}
const searchArr = search.split('&')
searchArr.forEach(v => {
const index = v.indexOf('=')
if (index !== -1) {
const name = v.substring(0, index)
obj[name] = v.substring(index + 1, v.length)
}
})
return obj
}
- hygk_request.js
import { Message } from 'element-ui'
import { Request } from './request'
export function hygkGet(url, params) {
const p = hygkGetWithLen(url, params)
return new Promise(resolve => {
p.then(res => {
resolve(res.data)
})
})
}
export function hygkGetWithLen(url, params) {
const p = Request.get(url, params)
return new Promise((resolve, reject) => {
const resData = { data: [], dataLen: 0 }
p.then(res => {
const { Err_No, Err_Msg, Total_Numbers, Data } = res.data
if (Err_No === '0') {
resData.data = Data
resData.dataLen = Total_Numbers
} else {
Message({
message: '异常:' + Err_Msg || '无返回',
type: 'error'
})
}
resolve(resData)
}).catch(error => {
Message({
message: '服务器异常',
type: 'error'
})
console.log(error)
resolve(resData)
})
})
}
export function hygkPost(url, params) {
const p = Request.post(url, params)
return new Promise((resolve, reject) => {
const cmdRes = { res: false, data: [] }
p.then(res => {
const { Err_No, Err_Msg, Data } = res.data
if (Err_No === '0') {
Message({
message: '操作成功',
type: 'success'
})
cmdRes.res = true
cmdRes.data = Data
} else {
Message({
message: Err_Msg,
type: 'error'
})
}
resolve(cmdRes)
}).catch(error => {
Message({
message: '服务器异常',
type: 'error'
})
console.log(error)
resolve(cmdRes)
})
})
}
export function hygkPut(url, params) {
const p = Request.put(url, params)
return new Promise((resolve, reject) => {
// data.res = true
const cmdRes = { res: false, data: [] }
p.then(res => {
const { Err_No, Err_Msg, Data } = res.data
if (Err_No === '0') {
Message({
message: '操作成功',
type: 'success'
})
cmdRes.res = true
cmdRes.data = Data
} else {
Message({
message: Err_Msg,
type: 'error'
})
}
resolve(cmdRes)
}).catch(error => {
Message({
message: '服务器异常',
type: 'error'
})
console.log(error)
resolve(cmdRes)
})
})
}
export function hygkDelete(url, params) {
const p = Request.delete(url, params)
return new Promise((resolve, reject) => {
let cmdRes = false
p.then(res => {
const { Err_No, Err_Msg } = res.data
if (Err_No === '0') {
Message({
message: '操作成功',
type: 'success'
})
cmdRes = true
} else {
Message({
message: Err_Msg,
type: 'error'
})
}
resolve(cmdRes)
}).catch(error => {
Message({
message: '服务器异常',
type: 'error'
})
console.log(error)
resolve(cmdRes)
})
})
}
- hygk_simple_mock.js
// get--无校验
export function get(url, Data) {
return {
url,
type: 'get',
response: params => {
return hygkResFormat(Data)
}
}
}
/**
* get--有参校验
* @param url
* @param data_fun
* @returns {{response: *, type: string, url: *}}
*/
export function get_with_response(url, data_fun) {
function response(config) {
return hygkResFormat(data_fun(config))
}
return {
url,
type: 'get',
response
}
}
// post--无校验
export function post(url, Data) {
return {
url,
type: 'post',
response: params => {
return hygkResFormat(Data)
}
}
}
export function post_with_response(url, data_fun) {
function response(config) {
return hygkResFormat(data_fun(config))
}
return {
url,
type: 'post',
response
}
}
// put--无校验
export function put(url, Data) {
return {
url,
type: 'put',
response: params => {
return hygkResFormat(Data)
}
}
}
// delete--无校验
export function Delete(url) {
return {
url,
type: 'delete',
response: params => {
return hygkResFormat()
}
}
}
export function hygkResFormat(Data = [], DataLen = Data.length, Err_Msg = '成功', Err_No = '0') {
return {
Err_Msg: Err_Msg,
Err_No: Err_No,
Total_Numbers: DataLen,
Data
}
}
- mock_utils.js
import Mock from 'mockjs'
import { param2Obj } from './ex_utils'
export function XHR2ExpressReqWrap(respond) {
return function(options) {
let result = null
if (respond instanceof Function) {
const { body, type, url } = options
result = respond({
method: type,
body: JSON.parse(body),
query: param2Obj(url)
})
} else {
result = respond
}
return Mock.mock(result)
}
}
export const mock_hour_date = function() {
const now = new Date(this.now)
now.setTime(now.getTime() - this.fromNowOn * 60 * 60 * 1000)
const sub = now
const year = sub.getFullYear() < 10 ? '0' + sub.getFullYear() : sub.getFullYear()
let month = sub.getMonth() + 1
month = month < 10 ? '0' + month : month
const day = sub.getDate() < 10 ? '0' + sub.getDate() : sub.getDate()
const hour = sub.getHours() < 10 ? '0' + sub.getHours() : sub.getHours()
return year + '-' + month + '-' + day + ' ' + hour + ':00:00'
}
export const mock_day_date = function() {
const now = new Date(this.now)
now.setTime(now.getTime() - this.fromNowOn * 24 * 60 * 60 * 1000)
const sub = now
const year = sub.getFullYear() < 10 ? '0' + sub.getFullYear() : sub.getFullYear()
let month = sub.getMonth() + 1
month = month < 10 ? '0' + month : month
const day = sub.getDate() < 10 ? '0' + sub.getDate() : sub.getDate()
return year + '-' + month + '-' + day + ' 00:00:00'
}
export const mock_month_date = function() {
const now = new Date(this.now)
now.setTime(now.getTime() - this.fromNowOn * 24 * 60 * 60 * 1000 * 30)
const sub = now
const year = sub.getFullYear() < 10 ? '0' + sub.getFullYear() : sub.getFullYear()
let month = sub.getMonth() + 1
month = month < 10 ? '0' + month : month
return year + '-' + month + '-' + '01' + ' 00:00:00'
}
- request.js
import { axios, axios_pure } from '../index'
class BaseRequest {
static _axios
static get(url, params) {
return new Promise((resolve, reject) => {
this._axios.get(url, {
params: params
}).then(res => {
resolve(res)
}).catch(err => {
console.log(err)
reject(err)
})
})
}
static post(url, params) {
return new Promise((resolve, reject) => {
this._axios.post(url, params)
.then(res => {
resolve(res)
})
.catch(err => {
console.log(err)
reject(err)
})
})
}
static put(url, params) {
return new Promise((resolve, reject) => {
this._axios.put(url, params)
.then(res => {
resolve(res)
})
.catch(err => {
console.log(err)
reject(err)
})
})
}
static delete(url, params) {
return new Promise((resolve, reject) => {
this._axios.delete(url, params)
.then(res => {
resolve(res)
})
.catch(err => {
console.log(err)
reject(err)
})
})
}
}
export class Request extends BaseRequest {
static _axios = axios
}
export class RequestWithoutBaseurl extends BaseRequest {
static _axios = axios_pure
}
框架使用
1. 在module中新建一个某模块的文件夹,比如我想实现登录认证相关的接口,那就创建一个`auth`的文件夹
2. 文件夹下生成3个文件,`api.js`、`mock.js`和`url.js`
3. 编写业务接口
这里以编写一个登录接口举例,接口的url为:/api/v1/auth,接口类型为:POST,接收参数:username和password
- 第一步,`url.js`添加url常量
url.js
export const AUTH = `/api/v1/auth`
- 第二步,`api.js`编写`axios`接口业务代码
api.js
import { hygkPost } from '@/service_api/utils/hygk_request' // 使用utils中封装好的方法
import { AUTH } from '@/service_api/module/auth/url' // 引入第一步中添加的url
export function requestLogin(username, password) {
return hygkPost(AUTH, { username, password })
}
- 第三步,`mock.js`编写`mock`业务代码,模拟后台数据返回
mock.js
import { post } from '@/service_api/utils/hygk_simple_mock'
import { AUTH } from '@/service_api/module/auth/url' // 引入第一步中添加的url
export default [
post(AUTH)
]
此时,业务代码编写完成,可在vue项目中测试接口的使用,首次使用需要在`main.js`中使用`index.js`,使用示例如下:
import { mock_init } from '@/service_api'
mock_init()