(component): [dropdown]指定下拉面板渲染容器

This commit is contained in:
sight 2022-07-04 15:09:13 +08:00
parent 780584e989
commit b9815b625b
4 changed files with 16 additions and 15 deletions

View File

@ -6,7 +6,7 @@ export default {
<script setup lang="ts"> <script setup lang="ts">
import "./index.less"; import "./index.less";
import { CSSProperties, inject, reactive, Ref } from "vue"; import { ComputedRef, CSSProperties, inject, reactive, Ref } from "vue";
import { import {
computed, computed,
nextTick, nextTick,
@ -52,7 +52,7 @@ export interface LayDropdownProps {
mouseLeaveDelay?: number; mouseLeaveDelay?: number;
focusDelay?: number; focusDelay?: number;
alignPoint?: boolean; alignPoint?: boolean;
renderToBody?: boolean; popupContainer?: string | HTMLElement | undefined;
} }
const props = withDefaults(defineProps<LayDropdownProps>(), { const props = withDefaults(defineProps<LayDropdownProps>(), {
@ -73,7 +73,6 @@ const props = withDefaults(defineProps<LayDropdownProps>(), {
mouseLeaveDelay: 150, mouseLeaveDelay: 150,
focusDelay: 150, focusDelay: 150,
alignPoint: false, alignPoint: false,
renderToBody: false,
}); });
const childrenRefs = new Set<Ref<HTMLElement>>(); const childrenRefs = new Set<Ref<HTMLElement>>();
@ -85,6 +84,13 @@ const { width: windowWidth, height: windowHeight } = useWindowSize();
const { x: mouseLeft, y: mouseTop } = useMouse(); const { x: mouseLeft, y: mouseTop } = useMouse();
const openState = ref(false); const openState = ref(false);
const containerRef = computed(() =>
props.popupContainer
// @ts-ignore
? document.querySelector<HTMLElement>(props.popupContainer) ?? document.body
: dropdownRef.value
) as ComputedRef<HTMLElement>;
const triggerMethods = computed(() => const triggerMethods = computed(() =>
([] as Array<DropdownTrigger>).concat(props.trigger) ([] as Array<DropdownTrigger>).concat(props.trigger)
); );
@ -142,10 +148,6 @@ const changeVisible = (visible: boolean, delay?: number) => {
} }
}; };
const containerRef = computed(() =>
props.renderToBody ? document.body : dropdownRef.value
);
const getElementScrollRect = (element: HTMLElement, containerRect: DOMRect) => { const getElementScrollRect = (element: HTMLElement, containerRect: DOMRect) => {
const rect = element.getBoundingClientRect(); const rect = element.getBoundingClientRect();
@ -603,9 +605,9 @@ defineExpose({ open, hide, toggle });
<div @click="handleClick()" @contextmenu="handleContextMenuClick"> <div @click="handleClick()" @contextmenu="handleContextMenuClick">
<slot></slot> <slot></slot>
</div> </div>
<Teleport :to="containerRef" :disabled="!renderToBody"> <Teleport :to="popupContainer" :disabled="!popupContainer">
<dl <dl
v-show="openState" v-if="openState"
ref="contentRef" ref="contentRef"
class="layui-dropdown-content layui-anim layui-anim-upbit" class="layui-dropdown-content layui-anim layui-anim-upbit"
:style="contentStyle" :style="contentStyle"

View File

@ -33,7 +33,7 @@ const isOpen = computed(() => {
placement="right-top" placement="right-top"
:autoFitMinWidth="false" :autoFitMinWidth="false"
:contentOffset="3" :contentOffset="3"
:renderToBody="true" popupContainer="body"
class="layui-sub-menu-popup" class="layui-sub-menu-popup"
> >
<li :class="['layui-nav-item']"> <li :class="['layui-nav-item']">

View File

@ -52,13 +52,12 @@ provideLevel(nextLevel);
const needPopup = ref(false); const needPopup = ref(false);
watchEffect(() => { watchEffect(() => {
const _isCollapse = isCollapse.value === true || isCollapse.value === "true"; const _isCollapse = isCollapse.value === true || isCollapse.value === "true";
if (_isCollapse) { if (_isCollapse && level.value === 1) {
// DOM //
setTimeout(() => { setTimeout(() => {
needPopup.value = isTree.value && _isCollapse; needPopup.value = isTree.value && _isCollapse;
}, 200); }, 200);
} else { } else {
// DOM
needPopup.value = isTree.value && _isCollapse; needPopup.value = isTree.value && _isCollapse;
} }
}); });

View File

@ -431,8 +431,8 @@ export default {
<template> <template>
<lay-switch v-model="collapse20"></lay-switch>&nbsp;&nbsp; <lay-switch v-model="collapse20"></lay-switch>&nbsp;&nbsp;
<lay-switch v-model="active20"> <lay-switch v-model="active20">
<template #onswitch-icon>😄</template> <template #onswitch-icon></template>
<template #unswitch-icon>🤔</template> <template #unswitch-icon></template>
</lay-switch> </lay-switch>
<br/> <br/>
<br/> <br/>