Do duplicated emitted events overlap/get called together in a parent component? - vue.js

I have two children components (CModal1 and CModal2) inside a parent component and both of them are wrapper in the ModalWrapper component. This wrapper component gives each modal a transition effect and a close event (an X button and a background that both emit the close event).
Right now, if the outter most layer's (Modal2) close buttons are clicked, it also closes Modal1. Is this because both #close events fire?
How can I remedy this? Should I put the wrapper of Modal2 inside the actual component, rather than wrapping it in the parent?
If I haven't explained things correctly, or you need more code/context, please let me know.
Cheers!
ParentComponent
<template>
<ModalWrapper
#close="modal1Open = false"
:isVisible="modal1IsVisible"
>
<CModal1
v-if="modal1IsVisible"
:formData="formData"
#close="modal1IsVisible = false"
#save-data="(val) => saveData(val)"
#open-modal-2-clicked="modal2Open = true"
/>
</ModalWrapper>
<ModalWrapper
#close="modal2Open = false"
:isVisible="modal2Open"
class="z-30"
>
<CModal2
v-if="modal2IsVisible"
#close="modal2IsVisible = false"
/>
</ModalWrapper>
</template>

Related

vue-tippy with a single global popup for multiple buttons

I'm using vue-tippy 6.0.0-alpha.63 for vue3.
I have a single component on the page which has a dynamic content and want to make a tooltip from it. This tooltip should be shown when user moves mouse over one of many buttons with class skill_tab. Those buttons are nested deeply inside the parent component of the current component.
I wrapped the component content with a <tippy> component and I'm trying to bind the tooltip to the buttons using to prop but it doesn't work.
I also tried using the triggerTarget prop providing the class .skill_tab as the value, but it looks like triggerTarget only works with refs.
Component for a button:
SkillTab.Vue
<div class="skill_tab">
...
</div>
Component for the tooltip:
SkillTooltip.Vue
<tippy followCursor=true to=".skill_tab" allowHtml=true placement="bottom-end" interactive=true>
<div id="skill_tooltip" class="skill_tooltip" :class="{active}" v-if="active">
...
</div>
</tippy>
Is there any way to bind the tooltip to all the buttons without passing refs via a global state or any other simple way?

pass to a component, via slot, a component that emits events

Hi all: I have a modal that I would like the buttons to be passed through slots, each with its own events. The problem is that when I click on the button, the event fires but the parent can't hear it.
<template>
<modal-detail v-if="viewModal" title="Modifica brands" #close="viewModal=false">
<!-- <template #header><p>ciao bob</p></template> -->
<template #body>
sdfgsfgddd
</template>
<template #actions>
<button-cancel buttonText="cancella" #click="$emit('close')"></button-cancel>
<button-confirm buttonText="conferma" #click="$emit('confirm')"></button-confirm>
</template>
</modal-detail>
</template>
The problem is thath #close="something" is never called.
Suggestion?
Thanks, all
It seems like you're using a custom component button. You either need to bind the #click handler to prop callback or use #click.native to apply the click handler.
To help debugging events and other issues such as with Vuex in the future, you can use the Vue browser dev tools.
If you install that plugin, and check the events stream you can see what events are being emitted by what. For example, if you haven't correctly set up your click handler with your custom button then you won't see the event getting emitted.

How to disable blur call on the active element from SwiperJS in onTouchStart handler?

Is it possible to disable this blur call on the active element from SwiperJS in the onTouchStart event handler?
Some background:
For touch and desktop devices I'm using swiper for forms on swiper-slides. Within a form I'm using vue-select (a combobox).
The Problem: When the user selects an entry, the entry get not selected on the first time but on the second time.
<div class="swiper-container">
<div class="swiper-wrapper">
<div class="swiper-slide">
<div>First form</div>
<v-select :options="selectionEntries"></v-select>
</div>
<div class="swiper-slide">
<div>Second form</div>
<v-select :options="selectionEntries"></v-select>
</div>
</div>
</div>
See also this example on codepen
I figured out that it seems to work correctly:
When I remove the blur-listener on the input field of the vue-select box. But it is used to close the selection list when the user leaves the field.
When I comment out this blur call in SwiperJS. I'm not sure why it is used there.
The first point is not an option, so is it possible to disable the blur call of SwiperJS via configuration?
Currently I'm using this workaround (SwiperJS V6.4.1):
const swiper = new Swiper(".swiper-container", {
// Workaround part 1:
touchStartPreventDefault: false
})
// Workaround part 2:
swiper.touchEventsData.formElements = 'notExistingHtmlTagName'
Part 1: To handle mouse down and click events on all elements, set the swiper parameter touchStartPreventDefault: false.
That will disable this code block: https://github.com/nolimits4web/swiper/blob/9dead9ef4ba5d05adf266deb7e3703ceb199a241/src/components/core/events/onTouchStart.js#L90-L97
Part 2: Set swiper.touchEventsData.formElements = 'undefined' to define nothing as formElements. That will disable the code block that calls blur: https://github.com/nolimits4web/swiper/blob/9dead9ef4ba5d05adf266deb7e3703ceb199a241/src/components/core/events/onTouchStart.js#L81-L88

How to use $refs in vue child component to shift focus?

I'm using this code to shift focus between text inputs in a v-for list:
HTML
<input :ref="'inputField' + index" #keydown.down="movedown(index)" type="text"
enter code here`v-model="todo.text">
JS
movedown: function(index){
this.$nextTick(() =>
this.$refs["inputField" + (1 + index)][0].focus()
);
}
It works fine when the input-fields are in the same component as the v-for. However, when I move the input-fields and the code to a child component I instead get an error that "this.$refs[("inputField" + (1 + index))] is undefined".
Here is a working JSFiddle where you can move down inputs with down-arrow: https://jsfiddle.net/Gnopps/w5xqa1r9/
Here is the same code, but in a child component and you can no longer move down: https://jsfiddle.net/Gnopps/y17en6o4/
Would anyone have any idea how I can fix this so that I can shift focus also with the input-fields in a child component?
ljubadr's answer in the comments worked perferctly. Basically move ref to parent and then this.$refs["inputField" + (1 + index)][0].$el.focus():
You can try something like this. When you press down, component will emit event to parent, and parent will focus next component

How do you wrap an achor tag in Vue2?

I am using Vue 2 and I am using an anchor tag as a "button" (for styling purposes with an svg).
The drawback of using an anchor tag in this way is that you can't disable it in the same way as a button.
I would like to make a vue component that simply wraps an anchor tag. I would like the component to pass all properties of the custom component onto the child anchor tag so that someone can use it like this:
<custom-comp id="closeButton" title="Close" class="c-btn" #click="close" :disable="true"></custom-comp>
I want to intercept the click on the child anchor tag and only emit that if the component is not disabled.
How can I achieve this?
You can't. disable property is used only in form elements. What you're looking for here is to use v-if:
<a id="closeButton" title="Close" class="c-btn" #click="close" v-if="isConditionMatched">
Only show if isConditionMatched returns true
</a>
Or, conditionally you can use return false statement inside your method:
close() {
if(!isConditionMatched) return false;
// continue your close function
}