From 88daef98fc2d5a4204f310bc4928a85a0382f17d Mon Sep 17 00:00:00 2001 From: "1445654576@qq.com" <1445654576@qq.com> Date: Sat, 4 Dec 2021 15:49:33 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E9=87=8D=E6=9E=84popover=E7=9A=84?= =?UTF-8?q?=E6=98=BE=E7=A4=BA=E6=96=B9=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../form/src/directive/d-validate-rules.ts | 2 +- .../form/src/form-control/form-control.tsx | 37 +++++++++++++++---- .../devui-vue/devui/form/src/util/index.ts | 21 +++++++++++ 3 files changed, 51 insertions(+), 9 deletions(-) diff --git a/packages/devui-vue/devui/form/src/directive/d-validate-rules.ts b/packages/devui-vue/devui/form/src/directive/d-validate-rules.ts index 87edc1a6..0fd26501 100644 --- a/packages/devui-vue/devui/form/src/directive/d-validate-rules.ts +++ b/packages/devui-vue/devui/form/src/directive/d-validate-rules.ts @@ -394,7 +394,7 @@ export default { const htmlEventValidateHandler = (e) => { const modelValue = e.target.value; if(messageShowType === MessageShowTypeEnum.popover) { - EventBus.emit("showPopoverErrorMessage", {showPopover: false, message: "", uid: dfcUID} as ShowPopoverErrorMessageEventData); + EventBus.emit("showPopoverErrorMessage", {showPopover: false, message: "", uid: dfcUID, popPosition} as ShowPopoverErrorMessageEventData); } validateFn({validator, modelValue, el, tipEl, isFormTag: false, messageShowType, dfcUID, popPosition}); } diff --git a/packages/devui-vue/devui/form/src/form-control/form-control.tsx b/packages/devui-vue/devui/form/src/form-control/form-control.tsx index 41d2e4af..55612f3a 100644 --- a/packages/devui-vue/devui/form/src/form-control/form-control.tsx +++ b/packages/devui-vue/devui/form/src/form-control/form-control.tsx @@ -1,8 +1,8 @@ -import { defineComponent, inject, ref, computed, reactive, onMounted } from 'vue'; +import { defineComponent, inject, ref, computed, reactive, onMounted, Teleport } from 'vue'; import { uniqueId } from 'lodash-es'; import { IForm, formControlProps, formInjectionKey } from '../form-types'; import { ShowPopoverErrorMessageEventData } from '../directive/d-validate-rules' -import { EventBus } from '../util'; +import { EventBus, getElOffset } from '../util'; import Icon from '../../../icon/src/icon'; import Popover from '../../../popover/src/popover'; import './form-control.scss'; @@ -21,10 +21,25 @@ export default defineComponent({ const showPopover = ref(false); const tipMessage = ref(""); const popPosition = ref("bottom"); + let rectInfo: Partial = { + width: 0, + height: 0 + }; + let elOffset = { + left: 0, + top: 0 + } + let popoverLeftPosition = 0 ; + let popoverTopPosition = 0 ; onMounted(() => { + const el = document.getElementById(uid); + elOffset = getElOffset(el); EventBus.on("showPopoverErrorMessage", (data: ShowPopoverErrorMessageEventData) => { if (uid === data.uid) { + rectInfo = el.getBoundingClientRect(); + popoverLeftPosition = popPosition.value === "top" || popPosition.value === "bottom" ? rectInfo.right - (rectInfo.width / 2) : rectInfo.right; + popoverTopPosition = popPosition.value === "top" ? elOffset.top + (rectInfo.height / 2) - rectInfo.height : elOffset.top + (rectInfo.height / 2); showPopover.value = data.showPopover; tipMessage.value = data.message; popPosition.value = data.popPosition as any; // todo: 待popover组件positionType完善类型之后再替换类型 @@ -51,14 +66,20 @@ export default defineComponent({ extraInfo, } = props; return
+ +
+ +
+
-
+
{ctx.slots.default?.()} - { showPopover.value && -
- -
- }
{ (feedbackStatus || ctx.slots.suffixTemplate?.()) && diff --git a/packages/devui-vue/devui/form/src/util/index.ts b/packages/devui-vue/devui/form/src/util/index.ts index a1fac48d..8130e097 100644 --- a/packages/devui-vue/devui/form/src/util/index.ts +++ b/packages/devui-vue/devui/form/src/util/index.ts @@ -10,3 +10,24 @@ export function hasKey(obj: any, key: string | number | symbol): boolean { if (!isObject(obj)) return false; return Object.prototype.hasOwnProperty.call(obj, key); } + +export function getElOffset(curEl: HTMLElement) { + let totalLeft = 0; + let totalTop = 0; + let par: Partial = curEl.offsetParent; + //首先把自己本身的相加 + totalLeft += curEl.offsetLeft; + totalTop += curEl.offsetTop; + //现在开始一级一级往上查找,只要没有遇到body,把父级参照物的边框和偏移相加 + while (par){ + if (navigator.userAgent.indexOf("MSIE 8.0") === -1){ //不是IE8才进行累加父级参照物的边框 + totalTop += par.clientTop; + totalLeft += par.clientLeft; + } + totalTop += par.offsetTop; + totalLeft += par.offsetLeft; + par = par.offsetParent; + } + return {left: totalLeft, top: totalTop}; +} + -- Gitee