Reputation: 31
I am new to Vue and have problem with Vue slots
. I have my component like this
<template>
<div class="dropDown__container">
<div
v-show="isOpened"
class="dropDown__content"
style="display:none;"
>
<slot />
<div class="dropDown__container-flex">
<span
class="dropDown__button"
@click="hideDropDown()"
>
Clear
</span>
<span
class="dropDown__button"
@click="hideDropDown(true)"
>
Submit
</span>
</div>
</div>
</div>
As you can see there is a method hideDropdown
which I would like to pass to my slot
. For your inforamtion I am using this slot
like this
<drop-down>
<div class="d-flex flex-row justify-content-between">
<ul id="priceFromList" class="hintList hintList--left">
<li class="hintList__item" v-for="price in lessThan(autocompletePricesDesktop, editableCriteria.Price.To)" @click="">
{{ price }}
</li>
</ul>
</div>
</drop-down>
What I want to achieve is to pass hideDropdown
method from component to slot
and use it on @click
for each li
. Is this possible ? I will apprecaite any help. Thanks in advance.
Upvotes: 3
Views: 5878
Reputation: 2152
The below code syntax is only useable from vue 2.6
Well you can actually achieve it. I am not sure if it's best practice. Here is how you can achieve it.
In your Parent component will bind the function to the slot
<slot :callableFunc="hideDropDown"/>
<template>
<div class="dropDown__container">
<div
v-show="isOpened"
class="dropDown__content"
style="display:none;"
>
<slot :callableFunc="hideDropDown"/>
<div class="dropDown__container-flex">
<span
class="dropDown__button"
@click="hideDropDown()"
>
Clear
</span>
<span
class="dropDown__button"
@click="hideDropDown(true)"
>
Submit
</span>
</div>
</div>
</div>
</template
In your child component you will utilize scoped-slots to access the binded function.
<drop-down>
<template v-slot:default="{ callableFunc}">
<div class="d-flex flex-row justify-content-between">
<ul id="priceFromList" class="hintList hintList--left">
<li class="hintList__item" v-for="price in lessThan(autocompletePricesDesktop, editableCriteria.Price.To)" @click="callableFunc()">
{{ price }}
</li>
</ul>
</div>
</template>
</drop-down>
Please take a look at the documentation https://v2.vuejs.org/v2/guide/components-slots.html#Scoped-Slots
Upvotes: 4
Reputation: 644
I think that in order to separate concerns, the dropdown-container should be the one deciding when to close the dropdown, and the slot-contained component should emit an event that can be used to indicate that something has happened, for example, that an item has been selected.
I would make the container listen to an event on the slot:
<slot v-on:item-selection="itemSelected" />
... and a function to receive the selected value:
function itemSelected(price) {
this.price = price;
hideDropdown();
}
In this case, the event is called item-selection
.
Then I would emit that event the contained component:
<li class="hintList__item" v-for="price in lessThan(autocompletePricesDesktop, editableCriteria.Price.To)" @click="itemClicked(price)">
... and a method in that component:
itemClicked(price) {
this.$emit('item-selection', price);
}
I hope this makes sense :-)
Upvotes: 0