3

I am trying to do an accordion component with vue 3 but the comparison situation seems a bit strange to me.

I'm trying to run a function in accordionitem ie toggle operation, but no matter what I did, I couldn't change the props value. where could i be doing wrong?

What I want to do is, mutliple when the toggle function is clicked? will look at him if not, I want to show whichever single one is. example is available in the link I mentioned below, but it was not possible for me to do this with vue 3

Link

faq.vue

<template>
  <accordion id="hello" :content="exampleData1"></accordion>
  <accordion id="hellomultiple" :content="exampleData2" multiple="multiple"></accordion>
</template>
<script setup>
import Accordion from "@/components/Accordion.vue";

const exampleData1 = [
 {
  id: 1,
  active: false,
  title: 'Crushing Spirits',
  details: `
      <p>You can crush me but you can't crush my spirit! Are you crazy? I can't swallow that. Who's brave enough to fly into something we all keep calling a death sphere? It doesn't look so shiny to me.</p>
      <ul>
        <li>I just want to talk.</li>
        <li>It has nothing to do with mating.</li>
        <li>Fry, that doesn't make sense.</li>
      </ul>
    `
 },
 {
  id: 2,
  active: false,
  title: 'Soundtracks',
  details: `
      <p>Ah, the 'Breakfast Club' soundtrack! I can't wait til I'm old enough to feel ways about stuff!</p>
    `
 },
 {
  id: 3,
  active: false,
  title: `The Letter Shaped Like a Man Wearing a Hat`,
  details: `<p>And then the battle's not so bad? You'll have all the Slurm you can drink when you're partying with Slurms McKenzie! Say it in Russian!</p>
      <p>Morbo can't understand his teleprompter because he forgot how you say that letter that's shaped like a man wearing a hat.</p>
   `
 }
]
const exampleData2 = [
 {
  id: 1,
  active: false,
  title: 'Celebration',
  details: `
      <p>Come on, this is a Bluth family celebration. It's no place for children.</p>
    `
 },
 {
  id: 2,
  active: false,
  title: 'Lighter Fluid and Wine',
  details: `
      <p>But where did the lighter fluid come from? Wine only turns to alcohol if you let it sit. But anyhoo, can you believe that the only reason the club is going under is because it's in a terrifying neighborhood?</p>
    `
 },
 {
  id: 3,
  active: false,
  title: `What's in Oscar's box?`,
  details: `
      <p>In fact, it was a box of Oscar's legally obtained medical marijuana. Primo bud. Real sticky weed.</p>
      <p>Great, now I'm gonna smell to high heaven like a tuna melt!</p>
    `
 }
]
</script>

Accordion.vue

<template>
 <dl class="accordion box" role="presentation">
  <accordion-item
      v-for="item in content"
      :multiple="multiple"
      :item="item"
      :groupId="id"
      :key="item.id">
  </accordion-item>
 </dl>
</template>

<script setup>
import AccordionItem from "@/components/AccordionItem.vue";

const props = defineProps({
 content: {type: Array, required: true},
 multiple: {type: Boolean, required: false},
 id: {type: String, required: false}
})
</script>

AccordionItem.vue

<template>
 <div :id="groupId + '-' + item.id" class="accordion-item" :class="{'is-active': item.active}">
  <dt class="accordion-item-title">
   <button @click="toggle" class="accordion-item-trigger">
    <h4 class="accordion-item-title-text">{{ item.title }}</h4>
    <span class="accordion-item-trigger-icon"></span>
   </button>
  </dt>
  {{ item.active }}
  <transition
      name="accordion-item"
      @enter="startTransition"
      @after-enter="endTransition"
      @before-leave="startTransition"
      @after-leave="endTransition">
   <dd v-show="item.active" class="accordion-item-details">
    <div v-html="item.details" class="accordion-item-details-inner"></div>
   </dd>
  </transition>
 </div>

</template>

<script setup>
const props = defineProps({
 item: {type: Object, required: true},
 multiple: {type: Boolean, required: false},
 groupId: {type: String, required: false}
})

function toggle(event) {
 props.item.active = !props.item.active
}


function startTransition(el) {
 el.style.height = el.scrollHeight + 'px'
}

function endTransition(el) {
 el.style.height = ''
}
</script>


1
  • 1
    Props are readonly in vue. You have to emit an event to the parent component so that it can update the value $emit('update:active', !props.item.active) Commented Dec 25, 2022 at 21:53

2 Answers 2

1

You need to make your array reactive with ref or reactive, then like commented, emit event from child and listen in parent. Take a look at demo HERE

Sign up to request clarification or add additional context in comments.

2 Comments

thank you for the answer but if you are aware it is not the same as the example i showed, so it doesn't work the same
the problem still continues
0

You cant change props in the component that declared them. what you can do:

  1. emit to the parent component to change the value.
  2. hold the data in a store and consume it from there and not as a prop

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.