Что-то случилось, когда я пытался разработать компонент слоя. Вот код:
// 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>
// Тест.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-индекс HTMLElements в слоте ["по умолчанию"].
К сожалению, я не могу найти дочерние элементы в useSlots()["default"]. Поэтому я пытаюсь позволить наблюдателю мутаций наблюдать за дочерним списком родителя.
Он отлично работает в одиночку (например, picture1 и picture2 в примере). Но он переопределяет друг друга, когда несколько Wrapper объединяются (например, picture3 в примере, z-индекс picture3, установленный wrapper3, переопределяется wrapper1). Это означает, что они имеют одного и того же родителя, так что потомки родителя всегда будут одинаковыми.
Итак, теперь проблема снова стала «Как получить HTMLElements в слотах» ... Может ли какой-нибудь мастер vuejs мне помочь?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Это можно было бы сделать намного проще, используя функции рендеринга Vue: Слоты рендеринга
const { createApp, h } = Vue;
const Wrapper = {
props: {
name: { type: String, default: "" },
zIndex: { type: Number, default: 0 },
},
setup(props, { slots }) {
let children = slots.default();
if (children) {
for (let i = 0; i < children.length; i++) {
children[i].props.style = `z-index: ${props.zIndex}`;
}
}
return () => slots.default()
}
}
const App = {
components: { Wrapper }
}
const app = createApp(App)
const vm = app.mount('#app')#app { line-height: 2; }
[v-cloak] { display: none; }<div id = "app" v-cloak>
<div class = "test">
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>
</div>
<script src = "https://unpkg.com/vue@3/dist/vue.global.prod.js"></script>Вам действительно не нужно div. Я обновил игровую площадку.
Спасибо за ваш ответ.
h('div', slots.default())Этот код создает элемент div, который не соответствует моим потребностям. Я не хочу создавать какой-либо элемент в качестве дочернего родителя, но хочу изменить дочерние атрибуты. Возможно ли это?