diff --git a/packages/opendesign/src/_utils/vue-utils.ts b/packages/opendesign/src/_utils/vue-utils.ts index 4a52e24a7b8fc798ab5662b597dc92916e71f0a4..f1e33db4482a2827726a5373dfecfeb98fcdb616 100644 --- a/packages/opendesign/src/_utils/vue-utils.ts +++ b/packages/opendesign/src/_utils/vue-utils.ts @@ -1,6 +1,7 @@ -import { Component, onMounted, ref, Slots, Slot, VNode, VNodeTypes, Comment, ComponentPublicInstance, watchEffect, Ref, isRef } from 'vue'; +import { Component, onMounted, ref, Slots, Slot, VNode, VNodeTypes, Comment, ComponentPublicInstance, watchEffect, Ref, isRef, watch } from 'vue'; import { isArray } from './is'; import { isHtmlElement } from './dom'; +import { log } from './log.ts'; // 来着vuejs/core // https://github.com/vuejs/core/blob/main/packages/shared/src/shapeFlags.ts @@ -160,52 +161,41 @@ export function useSlotFirstElement(): { setSlot: (nodes: VNode[] | undefined) = }; } +type ElementQuery = string | HTMLElement | ComponentPublicInstance | null | undefined; +const queryElement = (el: string | HTMLElement | null | undefined): HTMLElement | null => { + if (typeof el === 'string') { + return document.querySelector(el); + } else if (isHtmlElement(el)) { + return el; + } + return null; +}; export const resolveHtmlElement = ( - elRef: Ref | HTMLElement | string | undefined | ComponentPublicInstance + elRef: Ref | ElementQuery ): Promise => { - const queryElement = (el: string | HTMLElement | null | undefined): HTMLElement | null => { - if (typeof el === 'string') { - return document.querySelector(el); - } else if (isHtmlElement(el)) { - return el; - } - return null; - }; - return new Promise((resolve) => { + const resolveElement = (el: ElementQuery) => { + if (isComponentPublicInstance(el)) { + resolve(el.$el); + } else { + resolve(queryElement(el)); + } + }; if (isRef(elRef)) { - watchEffect(() => { - const { value } = elRef; - if (value) { - if (isComponentPublicInstance(value)) { - resolve(value.$el); + if (elRef.value) { + resolveElement(elRef.value); + } else { + const closeWatch = watch(elRef, (el, oldEl) => { + if (el) { + resolveElement(el); + closeWatch(); } else { - resolve(queryElement(value)); + log.warn(`resolveHtmlElement: elRef value is falsy, this might be a bug and could cause the promise to remain pending. Please check elRef.value: ${oldEl} -> ${el}`); } - } - }); - } else if (isComponentPublicInstance(elRef)) { - resolve(elRef.$el); - } else { - resolve(queryElement(elRef)); - } - }); -}; - -export const getHtmlElement = (elRef: Ref): Promise => { - return new Promise((resolve) => { - if (isHtmlElement(elRef.value)) { - resolve(elRef.value as HTMLElement); - } else if (typeof elRef.value === 'string') { - resolve(document.querySelector(elRef.value) as HTMLElement); + }); + } } else { - watchEffect(() => { - if (isHtmlElement(elRef.value)) { - resolve(elRef.value as HTMLElement); - } else if (elRef.value) { - resolve((elRef.value as ComponentPublicInstance).$el); - } - }); + resolveElement(elRef); } }); }; diff --git a/packages/opendesign/src/message/OMessage.vue b/packages/opendesign/src/message/OMessage.vue index 5994696663810ab6f83eaf6172d88decf95a1073..e24d938e6e046ec16053361a15e5cb05c5a13376 100644 --- a/packages/opendesign/src/message/OMessage.vue +++ b/packages/opendesign/src/message/OMessage.vue @@ -1,5 +1,5 @@