Tenho um componente filho dentro de um componente pai. Sempre que o componente filho é clicado, preciso aplicar uma classe chamada .selected
a ele.
Pai.vue
<template>
<ol>
<li v-for="(Contact, index) in Contacts">
<Component-Contact :ref="(el) => { RefContacts[index] = el}" @click="onClick(RefContacts[index])" :Contact="Contact" @Selected="(Data) => onSelected(Data)"/>
</li>
</ol>
</template>
<script>
import ComponentContact from '../components/Contact.vue'
....
setup() {
const RefContacts = ref([]);
function onSelected(Contact){
//Adds data received from child component to an array
}
onClick(el) {
el.toggleClass('selected') // Returns error saying toggleClass is not a function!!
}
const Contacts = ref();
onMounted(() => {
const Result = await axios.get(`/api/contacts`);
Contacts.value = Result.data
}
)
return {
Contacts, // An array of contacts from the DB
onSelected
}
}
</script>
Componente filho Contact.vue
<template>
<div style="cursor: pointer" @click="onClick($el, Contact)">
<p>{{Contact.Forename}}</p>
<p>{{Contact.Surname}}</p>
</div>
</template>
<script>
...
props: {
Contact: {
type: Object,
required: true
},
emits: 'Selected',
setup() {
function onClick(el, Contact) {
el.toggleClass('selected') // This works but I don't want to set it here in the child
return context.emit('Selected', {
FullName: Contact.forename + ' ' + Contact.surname
}
}
}
</script>
Como posso fazer o Vue aplicar a classe de .selected
dentro <Child-Component />
da Parent.vue
view? Quero defini-la no Parent (ou onde quer que esteja sendo usada) e então remover a classe quando o usuário terminar de fazer o que está fazendo. Sinto que isso é mais flexível do que defini-la dentro do componente filho.
Evite a manipulação do DOM o máximo possível.
Em vez de aplicar a classe você mesmo, deixe o Vue fazer isso:
Veja Ligações de classe e estilo .
Exemplo básico, onde apenas um item pode ser selecionado (selecionar outro desmarca o anterior):
E aqui está um onde você pode selecionar itens individualmente:
Em cada caso, estou mantendo um estado local mínimo (no pai). Quando o estado é modificado, o Vue atualiza o template.