vue3-composition-admin 是一个管理端模板解决方案,它是基于vue3,ts和element-plus,项目都是以composition api风格编写。
关于前端是否需要数据层,有许多需要探讨的部分,从客户端或者后端转前端的同学刚开始肯定也会有这个疑问,直接在使用返回内容真的好吗?
在使用JavaScript我是支持不写model的,充分保持数据的灵活性,如果不做缓存部分完全可以直接使用,也不会崩溃。
既然使用了typescript 就是想用类型检查等特性,点不出来是不是有些难受,model层也有利于维护代码。
翻了翻npm请求封装,并没有像iOS moya 这种返回model的库,于是我要写一个能返回model的网络请求。
vue项目绝大多数都是根据axios 进行网络封装,设计思想在网络请求和axios之间增加一层处理model转换,同事简化网络请求,所以起名axios-ampper。
设计图如下:
总体目标:更高效,快捷的将网络请求自动转换成model
/**
* @description: 封装请求类
* @param {Method} method 请求方式
* @param {APIPath} path 请求路径
* @param {RequestParams} params 参数
* @param {ContentType} contentType http配置
* @param {RequestOptions} optionsSource
* @return {*}
*/
request<T>(path?: string, method?: Method, params?: RequestParams, contentType?: ContentType, optionsSource?: HttpClientConfig): Promise<T | null>;
只有一个请求方法,参数枚举可选,更方便调用。对于restful api 更好的去复用。
为了避免点击过快,我们往往进行节流处理,网络请求封装自动处理。
可以设置间隔时间去阻止
/**
* @description: 验证是否是相同的url点击过快
* @param {string} url
* @param {Method} method
* @param {RequestParams} params
* @return {*}
*/
static hashUrlAndParams(
url: string,
method: Method,
params: RequestParams,
interval: number = 1000
) {
const identityCode = [url, method, qs.stringify(params)].join('&');
const currentTime = Date.parse(new Date().toString());
if (
currentTime - DuplicateRequest.lastRequestTimeStamp < interval &&
DuplicateRequest.lastIdentityCode === identityCode
) {
return true;
} else {
DuplicateRequest.lastRequestTimeStamp = currentTime;
DuplicateRequest.lastIdentityCode = identityCode;
return false;
}
}
只需传入要转换的model,实现接收。如下面代码:
https(false).request<RootObject<LoginModel>>('account/login', Method.POST, userInfo, ContentType.form)
我们以登录为例,实现完整的网络请求。
/*
* @Description: axios 封装网络请求
* @Author: ZY
* @Date: 2020-12-28 14:45:32
* @LastEditors: ZY
* @LastEditTime: 2021-02-02 17:41:39
*/
import { useStore } from '@/store'
import HttpClient, { HttpClientConfig } from 'axios-mapper'
import networkConfig from '@/config/default/net.config'
const https = (hasToken: Boolean = true) => {
const config: HttpClientConfig = {
baseURL: networkConfig.host,
headers: {
Authorization: hasToken ? useStore().state.user.token : ''
}
}
return new HttpClient(config)
}
export default https
安装json2ts 插件,或者其他。
新建文件之后,将json文件复制到粘贴板,然后 cmd+alt+V
or ctrl+alt+V
转换。
还是以用户管理为例:
/*
* @Description: 用户相关接口
* @Author: ZY
* @Date: 2020-12-28 14:40:50
* @LastEditors: ZY
* @LastEditTime: 2021-02-02 17:54:27
*/
import { RootObject } from '@/model/rootObject'
import { UserInfoModel, Users } from '@/model/userModel'
import https from '@/utils/https'
import { LoginModel } from '@/views/user-manager/login/model/loginModel'
import { RequestParams, ContentType, Method } from 'axios-mapper'
export const loginRequest = (userInfo: RequestParams) => {
return https(false).request<RootObject<LoginModel>>('account/login', Method.POST, userInfo, ContentType.form)
}
export const userInfoRequest = () => {
return https().request<RootObject<UserInfoModel>>('account/info', Method.GET, undefined, ContentType.form)
}
export const getUsers = (user: any) => {
return https().request<RootObject<Users>>('user/getUsers', Method.GET, user, ContentType.form)
}