Vue / Nuxt 3 Свернуть функцию компонента из родителя

Я создал повторно используемый компонент 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>

Не могли бы вы предоставить онлайн-репродукцию, чтобы мы могли протестировать и отладить компонент, пожалуйста?

Kapcash 05.04.2023 09:15
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
1
170
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы должны хранить и контролировать состояние в одном месте и использовать события для связи между компонентами.

Добавить 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

Другие вопросы по теме