名称:useHistoryStretch
需求来源
这个和路由操作相关的hooks,比较特殊一下,有点业务高度定制化的感觉,
业务扩展性,不通用
来源:
某天,产品说,需要开发一个功能,很简单,和另外一个功能很相似,大部分功能都相同,因为时间很紧张,能不能把原来的功能进行复用和完美兼容呢?然后就讨论想办法,在少动代码的情况,从菜单路由表来入手,同一个功能,多配置一份路由,改改路由名称,指向一个功能入口。
结果就变成了,路由地址和页面组件地址的关系是
多对1
的状态。
可不可以呢?
答案是没有什么不可以,但是出现了一个问题
:
在开发功能时,功能内子页面之间跳转,都是硬编码,使用的path
但是现在,在这个功能内部,跳转到目标地址时,需要考虑他的来源
比如我从课堂功能进入,和慕课功能进入逻辑是不一样。需要补前缀路由地址,如上图
课堂 -> class
慕课 -> mooc
我觉得这并不是一个很大的问题,但页面内跳转,硬编码不能搞成动态的
为了兼容这个方式,就需要从跳转地址入手,写一个公共方法,原先地址不变,在这个公共方法里面进行判断来源,这个来源是浏览器的访问地址前缀截取,截取后在进行拼写追加,是不是有思路了,但这种路由地址,在path层面就存在了父子关系依赖
说明:这种不能纳为框架正常模式,是对产品无声的对抗。
Hook设计实现
/**
* 获取拼装后的路由地址--追加模块标记
* 模板标记默认为,路由的一级 如: /A/A1,其中A为模块标记
* 例如:输入地址 /fanyi/md ==> /A/fanyi/md
* ---特定场景使用,如课堂和慕课模块,公用一套前端页面,路由地址不同,文件地址一致
* @param {*} url
*/
import router from '@/router'
/**
* 获取当前路由地址
* @returns
*/
const getCRouter = () => {
return router.currentRoute.value.path
}
/**
* 获取拼装后的路由地址
*
*/
const assemblyModule = (url) => {
const resPath = getCRouter().split('/')[1]
return `/${resPath}${url}`
}
const useHistoryStretch = async (options) => {
let path = ''
let query = null
if(typeof options == 'object' ){
path = options.path ?? ''
query = options.query || null
}else{
path = options
}
path = assemblyModule(path)
router.push({
path,
query
});
};
export default useHistoryStretch
业务使用
const goBack = () => {
useHistoryStretch({
path: "/coursePage/classPlan"
});
};
只适用于相同功能,公用模块的场景。
封装,完毕~~~
Hooks设计相关,暂时搞一段落,业务侧的hooks其实远远不止这些,今天还有想法,把框架层的字典访问做为hooks封装下....不是那么的紧急,想好了,后面再说....
后面准备把业务侧封装的loader管理器写一写....
针对业务侧一系列的Hooks封装,请看下方:
业务层-hooks封装设计
业务层-hooks封装之useAuth
业务层-hooks封装之useSessionStorage
业务层-hooks封装之usePreview
业务层-hooks封装之useExport
业务层-hooks封装之useBrowser
业务层-hooks封装之useFrameLayout
业务层-hooks封装之useHistory、useHistoryReplace