Vue3如何获取插槽内的HTMLElements?解决z-index覆盖问题
Vue插槽内HTMLElements获取与z-index冲突问题
我开发了一个名为Wrapper的空组件,目的是为默认插槽内的HTMLElements设置z-index,但遇到嵌套使用时z-index互相覆盖的问题,核心需求是准确获取插槽内的HTMLElements。
相关代码
Wrapper.vue
<template> <slot v-bind="attrs"></slot> </template> <script lang="ts" setup> import { defineProps, ref, watch, useAttrs, onMounted, onUnmounted, getCurrentInstance, } from "vue"; const props = defineProps({ name: { type: String, default: "" }, zIndex: { type: Number, default: 0 }, }); const attrs = useAttrs(); const inst = getCurrentInstance(); const observer = ref<MutationObserver | null>(null); watch( () => [props.zIndex, props.name], () => { setBrothersAttrs(); } ); onMounted(() => { let el = inst?.vnode.el; if (el) { if (!observer.value) observer.value = new MutationObserver(setBrothersAttrs); observer.value.observe(el.parentElement, { childList: true }); } setBrothersAttrs(); }); onUnmounted(() => { if (observer.value) observer.value.disconnect(); }); const setBrothersAttrs = () => { let el = inst?.vnode.el; let children = el?.parentElement?.children; if (el && children) { for (let i = 0; i < children.length; i++) { let bro = children[i]; if (bro === el) continue; bro.style.zIndex = props.zIndex; } } }; </script>
Test.vue
<template> <div class="test"> <Wrapper name="wrapper1" :z-index="1"> <img class="picture1" /> <div class="inner"> <Wrapper name="wrapper2" :z-index="2"> <img class="picture2" /> </Wrapper> </div> <Wrapper name="wrapper3" :z-index="3"> <img class="picture3" /> </Wrapper> </Wrapper> </div> </template> <script lang="ts" setup> import Wrapper from "./Wrapper.vue"; </script>
HTML渲染结果
<div class="test"> <img class="picture1" style="z-index: 1" /><!-- if no wrapper3, "z-index: 3" --> <div class="inner" style="z-index: 1"> <img class="picture2" style="z-index: 2" /> </div> <img class="picture3" style="z-index: 1" /><!-- if no wrapper3, "z-index: 3" --> </div>
问题说明
Wrapper组件的设计目标是为默认插槽内的元素设置z-index。尝试过用useSlots()["default"]但无法找到子元素,于是改用MutationObserver监听父元素的childList变化。
单独使用时功能正常(如picture1、picture2),但嵌套使用时,z-index会被互相覆盖。比如示例中的picture3,其由wrapper3设置的z-index会被wrapper1覆盖——原因是多个Wrapper共享同一个父元素,导致setBrothersAttrs方法会修改父元素下所有兄弟节点的z-index,包括其他Wrapper管辖的元素。
核心需求:如何准确获取当前Wrapper组件默认插槽内的HTMLElements,避免修改其他Wrapper管辖的元素?
内容的提问来源于stack exchange,提问作者XUX
相关产品推荐
相关产品推荐

