When attempting to develop a Layer component, I encountered some challenges. Here is the code:
// 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>
// Result in 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>
The Wrapper component is designed to set the z-index of HTMLElements in its slot["default"].
Although the mutation observer works fine individually (like picture1 and picture2 in the example), it causes issues when multiple Wrappers are used together (like picture3 in the example where picture3's z-index set by wrapper3 is overridden by wrapper1). This occurs because they share the same parent, resulting in shared children elements.
The problem now shifts to "How to retrieve HTMLElements in slots" once again. Can any Vue.js expert assist me with this issue?