Я создал повторно используемый компонент Collapse с помощью vue 3. Он работает, как и ожидалось. У меня проблема в том, что мне нужно контролировать 2 экземпляра коллапса с родительской/страницы. Я смог заставить родителя переключать определенный коллапс с помощью реквизита, но если я переключаюсь с родителя, а затем переключаю коллапс на себя, родителю теперь требуется два щелчка, чтобы снова переключиться. Я предполагаю, что данные на самом деле не обновляются? Не уверен, что есть лучший способ сделать это, не вникая в решение по управлению состоянием.
Свернуть.vue
<script setup>
const props = defineProps({
title: {
type: String,
required: true,
},
collapsed: {
type: Boolean,
default: false,
},
});
const isOpen = ref(props.collapsed);
watch(
() => props.collapsed,
(newValue) => {
isOpen.value = newValue;
}
);
const toggleCollapse = () => {
isOpen.value = !isOpen.value;
};
</script>
<template>
<div class = "flex flex-col ml-[20px] mb-2">
<button
@click = "toggleCollapse"
class = "text-left flex items-center relative font-source text-[19px] sm:text-[16px] lg:text-[19px] mb-2 font-semibold"
>
<IconCSS
:class = "{ 'rotate-90': isOpen }"
class = "text-3xl text-green absolute -left-7"
name = "mdi:chevron-right"
/>
{{ title }}
</button>
<div v-if = "isOpen">
<slot name = "collapseContent"></slot>
</div>
</div>
</template>
Родитель
<script setup>
const collapsePanels = ref([
{ id: 0, isVisible: false },
{ id: 1, isVisible: false },
{ id: 2, isVisible: false }
]);
const openCollapse = (id) => {
collapsePanels.value.forEach((el, index) => {
if (id === index) {
el.isVisible = !el.isVisible;
}
});
};
</script>
<template>
<button @click = "openCollapse(0)">Toggle Panel One</button>
<button @click = "openCollapse(2)">Toggle Panel Three</button>
<Collapse :collapsed = "collapsePanels[0].isVisible" title = "Collapse One">
<template v-slot:collapseContent>
<p>Collpase One Content</p>
</template>
</Collapse>
<Collapse title = "Collapse Two">
<template v-slot:collapseContent>
<p>Collpase Two Content</p>
</template>
</Collapse>
<Collapse :collapsed = "collapsePanels[2].isVisible" title = "Collapse Three">
<template v-slot:collapseContent>
<p>Collpase Three Content</p>
</template>
</Collapse>
Вы должны хранить и контролировать состояние в одном месте и использовать события для связи между компонентами.
Добавить id
опору
const props = defineProps({
id: {
type: Number,
required: true,
},
...
И toggle
событие в Collapse.vue
const emit = defineEmits(['toggle'])
const toggleCollapse = () => {
emit('toggle', props.id)
};
Затем используйте событие в родительском приложении с помощью @toggle = "toggleCollapse"
<Collapse :id = "0" @toggle = "toggleCollapse"...
и в <setup>
const toggleCollapse = (id) => {
openCollapse(id)
}
Вот рабочая SFC Playground
Не могли бы вы предоставить онлайн-репродукцию, чтобы мы могли протестировать и отладить компонент, пожалуйста?