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
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 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" :>
<dt >
<button @click="toggle" >
<h4 >{{ item.title }}</h4>
<span ></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" >
<div v-html="item.details" ></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>
CodePudding user response:
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
CodePudding user response:
You cant change props in the component that declared them. what you can do:
- emit to the parent component to change the value.
- hold the data in a store and consume it from there and not as a prop