前言
纯菜鸡记录
业务场景
- 拆分思路:
- 根据业务,可以分成 nav(面包屑+树状导航)、page(内容展示);根据内容展示的不同,还可以继续拆分
- 根据项目结构,可以分为xxx.vue(页面)、data_xx.ts(接口)、use_xx.ts(逻辑),还有其他文件,如常量管理、路由管理、鉴权管理等
- 拆分方向:
拆分足够细,尽量使用函数式编程(有很多方向,只是选择了其中的一种)
- 以拆分nav(面包屑+树状导航)为例
文件结构:
/*
* bread-crumb.vue
* 面包屑页面:包含页面需要的数据以及跳转功能
* data_nav.ts
* nav(面包屑+树状导航)相关接口文件及简单数据处理
* index.vue
* nav(面包屑+树状导航)入口页面(布局、提供各个子页面所需的数据
* interface.ts
* typescript相关接口定义等
* tree.vue和tree_menu.vue
* 树状导航:包含页面需要的数据以及跳转功能
* use_base.ts
* 组装全局所需的一些字段,如 id 等
* use_nav.ts
* 组装nav(面包屑+树状导航)所需的数据
* use_router.ts
* 跳转功能封装
*/
- 不同业务模块之间的数据交互(在交互设计上,需要尽可能做到功能分离化)
在nav(面包屑+树状导航)模块定义:
/**
* use_base.ts
* 基本信息钩子:暴露了基本数据base,并且provide了可供全局使用的数据和方法
*/
import { provide, computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { BASE, BASE_ID_OPEN } from './constant'
function fmtId(v?: string) {
return v || ''
}
export function useBase() {
const router = useRouter()
const route = useRoute()
const base = computed(() => {
return {
id: fmtId(route.query.id as string),
parentId: fmtId(route.query.parentId as string)
}
})
provide(BASE, base)
provide(BASE_ID_OPEN, (id: string) => {
router.push({ query: { id } })
})
return {
base
}
}
在内容展示模块使用:
// use_main.ts
import { computed, ComputedRef, inject, watch } from 'vue'
import { BASE, CHAIN, BASE_ID_OPEN } from './constant'
import { TribeData } from './interface'
export function useMain() {
const base = inject<ComputedRef<{ id: string, parentId: string }>>(BASE, computed(() => ({
id: '',
parentId: ''
})))
const openId = inject<(id: string) => void>(BASE_ID_OPEN)
const updateChain = (name: string) => {
const lastChainItem = chain.value[chain.value.length - 1]
lastChainItem.label = name
}
return {
base,
openId,
chain,
updateChain
}
}
这样,在内容展示模块就可以使用这些基本信息和方法了。