Converting "[object SVGGElement]" to HTML Vue3 - javascript

I want to reactively call a custom bootstrap popover component based on which svg the user is hovering over throughout the page. It is called by:
<template>
<popover v-if="node != null">
<template #content>
Reached
</template>
<template #caller>
{{node}}
</template>
</popover>
</template>
However, {{node}} is returning "[object SVGGElement]" rather than the expected html object.
If I use {{node.outerHTML}} it returns a string literal: "svg id="test"></svg"
Any suggestions to have it return as an html object? For example:
...
<template #caller>
<svg id="test"></svg>
</template>
...

The Svg is an SVGGElement. I suggest capturing the mouse mouseover event to set the Popover position.

Related

Why can't I call a method when clicking on this span text?

Using Vue 3 I am trying to call the handleViewAuditClick method when someone clicks the span.
I have added #click="handleViewAuditClick" event to the span text but clicking the text does not call the method.
If I change it so the text is wrapped in a div instead that works. Although I have no idea why that works. Using a div is also not a good solution for me because it changes the text to be multi-lined which I don't want.
So how do I call the handleViewAuditClick when clicking the span text?
<template>
<v-alert-banner design="positive">
New audit is ready.
<span #click="handleViewAuditClick">
Click here to view.
</span>
</v-alert-banner>
</template>
<script setup>
import VAlertBanner from 'src/components/VAlertBanner.vue';
const handleViewAuditClick = () => {
console.log('clicked');
};
</script>
And this is what the child v-alert-banner component looks like:
<template>
<q-banner dense rounded :class="classValue" class="full-width">
<template #avatar>
<q-icon :name="iconNameValue" size="sm" />
</template>
<slot></slot>
</q-banner>
</template>

Using v-tooltip on custom (non native) component

I have a custom component which is being used application wide. But, in some place I want to show tooltip on hover on this component, according to vuetify docs this should work but it doesn't because <custom-component /> is not a native component.
And to have this functionality for native component a .native modifier is to be used.
Example: #click.native="someMethod"
How can I do that to show v-tooltip.
I have tried wrapping <custom-component /> in a div but it isn't working.
Below is sample code to get the gist.
<v-tooltip>
<template v-slot:activator="{ on }">
<custom-component v-on="on" />
</template>
<span>Tooltip text</span>
</v-tooltip>
custom-component should forward events from an element with v-on="$listeners"
https://v2.vuejs.org/v2/guide/components-custom-events.html#Binding-Native-Events-to-Components
I have tried wrapping <custom-component /> in a div but it isn't working
If you do this then the events need to be bound to the div instead:
<div v-on="on">
<custom-component />
</div>

Vuetify on mouseover toggle data object within array list

I am trying to implement a functionality which will toggle a Vuetify badge element for each array object within the list when the containing div has been hovered over.
I am able to create a hover like functionality within v-for array list using css, which is fairly simple but how can I achieve similar outcome using vuetify components? As I have not found any questions discussing this or demonstrating it, assume it is possible. Have looked into
First Link
Second Link
Second Link
And much more but have not found similar enough example of what I desire.
I have added codepen example of what I currently have.
The badge should only appear on the element which is currently being hovered, however all badge elements are being executed when any element has been hovered on.
CodePen Link
Maybe I have missed out something obvious
HTML Part
<template>
<div id="app">
<div>My favourite fruit is <b>{{favouriteFruit}}</b></div> <br>
<div v-for="(dataArray, index) in testArray" #click="setCurrent(dataArray.name)">
<v-badge
:color="computedFavFruitColor[index]"
right
v-model="show"
>
<template v-slot:badge>
<span><v-icon color="#ECF0FF">{{computedFavFruit[index]}}</v-icon></span>
</template>
<div #mouseover="show = true" #mouseleave="show = false">
{{dataArray.name}}
</div>
</v-badge>
</div>
</div>
</template>
Any further help of suggestions regarding this manner would be appreciated.
While the show property is global, it counts for every item you hover. You want to target the element you hover. So I suggest to keep track of the index of the item you hover like this: https://codepen.io/reijnemans/pen/JjPrayp?editors=1010
<div v-for="(dataArray, index) in testArray" #click="setCurrent(dataArray.name)">
<v-badge
:color="computedFavFruitColor[index]"
right
>
<template v-slot:badge>
<span v-if="show == index"><v-icon color="#ECF0FF">{{computedFavFruit[index]}}</v-icon></span>
</template>
<div #mouseenter="show = index" #mouseleave="show = null">
{{dataArray.name}}
</div>
</v-badge>
</div>
And show = null ipv show = true in data block of vue

Parent component slots inside children component vue 2.x

I have a modal that have 2 slots, default slot and buttons slot, in the default slot i will set the content of the modal (in this case i will use an alert) and in buttons slot i will add some buttons (in this case a delete button).
Now i want to create a component that will contain the alert and the delete button mentioned before. but the alert will be in the default slot and the button in the buttons slot of the modal.
If i use the code below in the modal component like this, it will show the modal with the alert
<modal>
<template v-slot:default>
<v-alert type="warning" :value="true">
¿Are you sure you want to delete {{ text }}?
</v-alert>
</template>
<template v-slot:buttons>
<v-btn color="error" #click="clicked">Delete</v-btn>
</template>
</modal>
Now what i want is to be able to just set a component inside the modal like this
<modal :title="title" :show="show" #close="show = false">
<modal-elim :text="'delete something'"></modal-elim>
</modal>
I want to do this, so i can dynamically change the content of the modal in the future, and reuse the same modal layout.
As you can see the modal-elim component will have the alert and the button shown before, but they must apper in the slots of the modal component, i have tried this
<template>
<div>
<template v-slot:default>
<v-alert type="warning" :value="true">
¿Estas seguro que deseas eliminar {{ text }}?
</v-alert>
</template>
<template v-slot:buttons>
<v-btn color="error" #click="clicked">Enviar</v-btn>
</template>
</div>
</template>
<template v-slot> can only appear at the root level inside the receiving the component
When i trie to wrap the elements inside the slot it throw an error
It is posible to add the parent slot iside the child component?
How can i do that?
How else can i do a workaround this?
in the ModalElim component? i have tried this but it throw an error.

Is there a way to 'pipe-together' slots in nested components in Vue?

Let's say I'm developing an enhanced popper.js for Vue and I'm about to give it some additional functionality. This is how the very (child) component looks like:
<popper>
<div :is="tag" class="popper">
{{ content }}
</div>
<button class="btn btn-primary" slot="reference">
Reference Element
</button>
</popper>
As you can see, for it to work it requires defining reference element right beneath the ".popper" div with a slot="reference" attribute.
Question:
How to turn my enhanced-popper component into a re-usable entity, aka be able to pass slotted data indirectly - from
<enhanced-popper> //referenced element// </enhanced-popper> so that it has the slot="reference" attribute inside the child (popper.js-based) component?
What did not work:
Employing slots and having the attribute in a component passed in by the parent component does not yield desired results, as it does not get rendered at all.
<popper>
<div :is="tag" class="popper">
{{ content }}
</div>
<slot></slot>
</popper>
To ensure having the attribute out there I also tried to replace said button in the child component with a named slot inside a slot and go like this in my enhanced-popper:
<slot name="reference">
<slot></slot>
</slot>
That way the first slotted component has the attribute - and it almost works, but since there are two "slot-layers" (no idea how to call it), the referenced component is not the first one as a child, and popper gets mis-positioned.
Cheers,
Paco

Categories