前端现在扮演的角色越来越重,从Java手中夺取一部分,现在有横向进军桌面的移动端,所谓是框架百家争鸣,但最终还是JS,今天就看看vue框架的嫁衣。
本文涉及到装饰器的使用,横向切面在轻松优雅的实现各种功能包括,防抖节流,数据缓存,本地缓存,loading等功能,个人认为以后趋势。也涉及到fetch的封装,具体细节,下节细说。
api的装饰
Java有DDD开发模式,相对比以前的mvc更加注重了模块化,功能化,前端的话没必要这么复杂,但是还是要做些嫁衣和模块化开发:
@Controller({ path: "/param/api/v1/publ", token: "no" })
export class ParamApi {
@Get("/enums/{enumTypeId}")
public async paramApi(params: MyRequest) {
return request(params)
}
@Put("/camp/ballot/application/{applicationId}/sequence")
public async changeChoiceSeqApi(params: MyRequest) {
return request(params)
}
@Delete("/balloting/application/{applicationId}/choices/{choiceId}")
public async deleteChoiceApi(params: MyRequest) {
return request(params)
}
@Post({ path: "/publ/registerWithEmail", timeout: 60000 })
public async registerApi(params: MyRequest) {
return request(params)
}
这样的写法条例清晰,每个接口和Java对应,每个接口做什么事情什么意思清清楚楚(post,get,delete),如果Java有修改,这边一一对应不会乱。接下来就是request:
const server = fetch.create({
baseURL: "/rest",
headers: {
channel: "**"
}
})
server.interceptors.request.use(config => {
const token = getKeyValue({ key: "accessToken" })
if (token && config.token != "no") {
config.headers["Authorization"] = token
}
config.headers["Accept-Language"] = getKeyValue({ key: "language" })
return config
})
server.interceptors.response.use(undefined, err => {
const config = err.config
if (!config || !config.retry) return Promise.reject(err)
config._retryCount = config._retryCount || 0
if (config._retryCount >= config.retry) return Promise.reject(err)
config._retryCount += 1
return server.request(config)
})
这里采用了fetch来访问和操纵 HTTP,这里可以添加headers,设置接口重试,可以处理无感知token refresh,可以解析返回值然后做特殊处理等,每块都是各自的功能。到这api层差不多了。
store层装饰
store层做中转,相当于Java的service层,做些功能性等操作:
@Module({ dynamic: true, store, name: "common", namespaced: true })
class Common extends VuexModule implements CommonState {
public file = ""
public sliderCache: any = {
facility: {},
programme: {}
}
public routeCache: unknown = []
@Action
@Loading
@Throttle(100)
@Debounce
@CacheSession({ key: "#facility.waterReviewData", value: "waterReviewData" })
async upload(param: MyRequest) {
return await fileApi.uploadApi(param)
}
@Mutation
@CacheImmediately({ key: "#common.routeCache", value: "routeCache" })
public SET_ROUTE_CACHE(data: any) {
this.routeCache = data
}
这里的可以做好多事情,防抖节流,是否需要loading,是否需要缓存到localStorage,是否需要缓存sessionStorage,只需要加一个注解就可以,无入侵式,需要什么加什么,清楚明了。
业务层
getCategoryEnums(): void {
ParamModule.getParam({
path: { enumTypeId: "pgm_application_category" }
})
.then(checkCode)
.then((res: any) => {
this.categoryList = res
this.getShoppingCartCategory()
})
}
业务层也很清晰,是路径传参还是问号传参一看就知道。
这些是总结其他框架的优化,还有很多,这一期先到这,只是单纯分享,认不认同无所谓