Skip to content

Commit

Permalink
feat: 优化组件之间初始化的发布订阅模式
Browse files Browse the repository at this point in the history
1. 简化 uid 生成
3. 组件之间发布订阅模式简化
2. 修复 contextMenu 无法在覆盖物上生效
  • Loading branch information
yue1123 committed Dec 2, 2023
1 parent abf2ea3 commit 4dbcd9c
Show file tree
Hide file tree
Showing 9 changed files with 49 additions and 35 deletions.
1 change: 1 addition & 0 deletions packages/components/contextMenu/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
const getParentInstance = inject('getOverlayInstance', () => null)
const vueEmits = defineEmits(['initd', 'unload', 'open', 'close'])
let contextMenu: BMapGL.ContextMenu
const { ready } = useParentComponentEffect((map: BMapGL.Map) => {
const target = getParentInstance() || map
const cal = () => {
Expand Down
9 changes: 4 additions & 5 deletions packages/components/map/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@
warn,
type MapType,
type Point,
nanoid,
getInitEventKey,
isClient
} from '../../utils'
import { useInstanceId } from '../../hooks'
export interface MapDisplayOptions {
/**
* 是否显示地图上的地点标识
Expand Down Expand Up @@ -282,7 +282,7 @@
// 是否初始化
let initd = ref<boolean>(false)
const instance = getCurrentInstance()
const instanceId = nanoid(8)
const instanceId = useInstanceId()
// 地图初始化的发布
const { emit } = usePubSub()
const width = computed(() => (isString(props.width) ? props.width : `${props.width}px`))
Expand Down Expand Up @@ -401,7 +401,7 @@
instance,
BMapGL: window.BMapGL
}
emit(getInitEventKey(instanceId), event)
emit(instanceId, event)
vueEmits('initd', event)
initd.value = true
})
Expand Down Expand Up @@ -589,7 +589,6 @@
setDragging
})
provide('getMapInstance', () => map)
provide('parentComponentId', instanceId)
provide('baseMapSetCenterAndZoom', (_center: { lng: number; lat: number }) => setCenterAndZoom(_center))
provide('baseMapSetDragging', (enableDragging: boolean) => setDragging(enableDragging))
provide('getBaseMapOptions', () => props)
Expand Down
1 change: 1 addition & 0 deletions packages/hooks/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export * from './useAddressGeocoder'
export * from './usePointGeocoder'
export * from './usePointConvertor'
export * from './useDefaultMarkerIcons'
export * from './useInstanceId'
8 changes: 8 additions & 0 deletions packages/hooks/useInstanceId.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { provide } from 'vue'
import { getUid } from '../utils'

export function useInstanceId() {
const instanceId = getUid()
provide('parentComponentId', instanceId)
return instanceId
}
34 changes: 17 additions & 17 deletions packages/hooks/useParentComponentEffect.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,40 @@
import { onBeforeUnmount, inject, getCurrentInstance, onMounted } from 'vue'
import usePubSub from './usePubSub'
import { error, noop, getInitEventKey } from '../utils'
import { error, noop } from '../utils'
import { useInstanceId } from './useInstanceId'

/**
* ### 监听父组件初始化,初始化完成调用 initdCallback 初始当前组件
* root map 组件需要加载 sdk,所以它必定是异步的,
* 子组件的初始化依赖于 root map 组件,当子组件初始化初始化root map 组件未初始化完成,就需要订阅他的初始化完成时间,这个事件触发了之后,再初始化当前组件,
* 这是一个典型的发布订阅模式
* 除根组件 Map 外,每个组件都可以是订阅者和发布者
*
* - 比如下面的组件层级:
* ```text
* |___Map 发布
* |___|__Circle 订阅
* |___|___ContextMenu 订阅 / 发布
* |___|___|___ContextMenuItem 订阅
* |___|__Circle 订阅 / 发布
* |___|___Marker 订阅 / 发布
* |___|___|___ContextMenu 订阅
* ```
* @param initdCallback 初始当前组件
* @returns
*/
export default function useParentComponentEffect(initdCallback: (map: BMapGL.Map) => void | VoidFunction, emitId = '') {
export default function useParentComponentEffect(initdCallback: (map: BMapGL.Map) => void | VoidFunction) {
const { on, off, emit } = usePubSub()
const comInstance = getCurrentInstance()
const currentInstanceId = useInstanceId()
const { emit: vueEmit } = comInstance || { emit: noop }

const getMapInstance = inject<(() => BMapGL.Map) | undefined>('getMapInstance', undefined)
// get root BMap component uid
const parentComponentId = inject<string | void>('parentComponentId', undefined)
const uid = typeof parentComponentId !== 'undefined' ? parentComponentId : emitId

const parentUid = parentComponentId || ''
const componentName = comInstance ? comInstance.type.name || '' : ''
if (typeof getMapInstance === 'undefined') {
__DEV__ && error((comInstance && comInstance.type.name) || '', 'must be a child node of the Bmap component')
__DEV__ && error(componentName, 'must be a child node of the Bmap component')
return { ready: noop }
}

const map = getMapInstance()
const eventKey = getInitEventKey(uid)
let clearEffect: void | VoidFunction
const initCallbackProxy = (event: { map: BMapGL.Map }) => {
clearEffect = initdCallback(event.map as BMapGL.Map)
Expand All @@ -44,29 +44,29 @@ export default function useParentComponentEffect(initdCallback: (map: BMapGL.Map
if (map) {
initCallbackProxy({ map })
} else {
on(eventKey, initCallbackProxy)
on(parentUid, initCallbackProxy)
}
})

onBeforeUnmount(() => {
try {
clearEffect && clearEffect()
} catch (e: any) {
error('BMapGL SDK', e.message)
error(componentName, e.message)
}
vueEmit('unload')
off(eventKey, initCallbackProxy)
off(parentUid, initCallbackProxy)
})

return {
ready: (map: BMapGL.Map, instance: any) => {
const event = {
const eventPayload = {
map,
instance,
BMapGL: window.BMapGL
}
vueEmit('initd', event)
emitId && emit(eventKey, event)
vueEmit('initd', eventPayload)
emit(currentInstanceId, eventPayload)
}
}
}
10 changes: 10 additions & 0 deletions packages/utils/callWhenDifferentValue.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* watch 回调辅助前置判断
* @param cal watch 处理函数
* @returns (nv: T, ov: T) => void
*/
export function callWhenDifferentValue<T>(cal: (v: T) => void): (nv: T, ov: T) => void {
return (nv: T, ov: T) => {
if (nv === ov || (nv !== ov && JSON.stringify(nv) !== JSON.stringify(ov))) cal(nv)
}
}
5 changes: 5 additions & 0 deletions packages/utils/getUid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
let id = 0

export function getUid() {
return `${id++}`
}
4 changes: 3 additions & 1 deletion packages/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ export * from './is'
export * from './pluginLoader'
export * from './types'
export * from './pathPointsToMapPoints'
export * from './nanoid'
export * from './getUid'
export * from './proxyValue'
export * from './conditionalCall'
export * from './callWhenDifferentValue'
12 changes: 0 additions & 12 deletions packages/utils/nanoid.ts

This file was deleted.

0 comments on commit 4dbcd9c

Please sign in to comment.