Manipulating tailwind data using Vue - vue.js

I am using tailwind (flowbite) css for web components that comes with respective css and js.
I want to implement acordion component (https://flowbite.com/docs/components/accordion/) and fill its data dynamically using Vue.
<li
v-for="({ username, email, role }, index) in myUsers"
:key="username"
>
<h2 v-bind:id="`accordion-open-heading-${{ index }}`">
<button
type="button"
class="flex items-center justify-between w-full p-2 font-medium text-left text-gray-500 border border-gray-200 focus:ring-4 focus:ring-gray-200 dark:focus:ring-gray-800 dark:border-gray-700 dark:text-gray-400 hover:bg-gray-100 dark:hover:bg-gray-800"
v-bind:data-accordion-target="`#accordion-open-body-${index}`"
aria-expanded="true"
v-bind:aria-controls="`accordion-open-body-${index}`"
>
Seems that the vue part works fine, it grabs the data, creates respective HTML li - lists and changes its HTML tags for accordion access (accordion-open-body-1, accordion-open-heading-1 ..)
However, JS that cmes with flowbite can not grab that changes and throws the following error:
Please, advice how can I fix this issue.

Change
<h2 v-bind:id="`accordion-open-heading-${{ index }}`">
to
<h2 v-bind:id="`accordion-open-heading-${ index }`">
👆 👆

Related

JAMStack: how to impelement E-Mail Services or simple reactive variables?

I'm currently working on a marketing website for a client. Because SSR would be over-engineered and I'm curious about JAMStack, I decided to make a static website using Nuxt, because I'm already familiar with it.
So I managed to implement Tailwind, which works fine, also when the static site is generated and live on Github pages for example. Now I want to add a feature like a send e-mail form or a menu with a toggle icon.
The simplest solution I could think of for the menu would be a reactive variable and conditional rendering using tailwind. This works fine on localhost using npm run dev, but I can't figure out how to implement this on the generated static site.
I couldn't even manage to fire a click event to a defined method in the script tag.
That's how I would do the burger menu with nuxt SRR, how can I implement something like this in static generated nuxt?
<template>
<div>
<nav
class="flex p-5 items-center fixed w-full border-b-4 border-green bg-white z-50 duration-300 transform justify-between">
<div>
<div><img src="logo.png" class="max-h-6 md:max-h-10" /></div>
</div>
<div class="w-10 h-5 flex flex-col relative cursor-pointer" id="nav-menu" #click="menuOpen = !menuOpen">
<div class="w-full h-1 bg-green absolute duration-200 transform "
:class="[menuOpen ? 'rotate-45 translate-y-2' : 'burger-hover1']" id="menu-first"></div>
<div class="w-full h-1 bg-green absolute bottom-0 duration-200 transform "
:class="[menuOpen ? '-rotate-45 -translate-y-2' : 'burger-hover2']" id="menu-second"></div>
</div>
</nav>
<Transition>
<div v-if="menuOpen" class="fixed w-screen h-screen bg-white pt-20 z-30 space-y-10 text-xl text-center">
<div class="mt-20" #click="menuOpen = !menuOpen">
<nuxt-link to="/">Start</nuxt-link>
</div>
<div #click="menuOpen = !menuOpen">
<nuxt-link to="/partner">Partner</nuxt-link>
</div>
<div #click="menuOpen = !menuOpen">
<nuxt-link to="/kontakt">Kontakt</nuxt-link>
</div>
<div #click="menuOpen = !menuOpen">
<nuxt-link to="/impressum">Impressum</nuxt-link>
</div>
</div>
</Transition>
</div>
</template>
<script>
export default {
name: 'Navbar',
data() {
return {
menuOpen: false
}
}
}
</script>
That's how it looks on localhost. When the static site is hosted, it won't toggle the menu.

Why is my transition not working on "leave"?

I have a global confirmModal.vue which looks like this:
<template>
<Transition
appear
enter-from-class="opacity-0"
enter-to-class="opacity-100"
leave-from-class="opacity-100"
leave-to-class="opacity-0"
>
<div
#click="$emit('cancel')"
class="bg-black/50 z-50 fixed inset-0 flex justify-center items-center transition duration-300 ease-in-out p-8 cursor-pointer"
>
<Transition appear enter-from-class="scale-50" enter-to-class="scale-100">
<div
#click.stop
class="flex flex-col gap-4 shadow-2xl p-8 rounded min-w-[300px] max-w-[480px] bg-lf-white transition duration-300 ease-in-out cursor-auto"
>
<h3 class="font-medium text-2xl">{{ title }}</h3>
<p>{{ text }}</p>
<div class="flex justify-end gap-2">
<Button #click="$emit('cancel')" variant="white">Annuler</Button>
<Button #click="$emit('confirm')">Supprimer</Button>
</div>
</div>
</Transition>
</div>
</Transition>
</template>
The first transition adds a fade in effect to the backdrop while the nested transition adds a smooth apparition effect for the modal itself.
It works fine but what I don't understand is that when I close the modal, the leave part of the transition does not trigger at all.
This is what the component calling this modal looks like:
<ConfirmModal
v-if="showConfirmModal"
title="Suppression"
text="Êtes-vous sûr de vouloir supprimer cet article ?"
#cancel="handleHideConfirmModal"
#confirm="handleConfirmAction"
/>
Here's a gif of what it's currently looks like:
EDIT: I achieved the wanted result by wrapping ConfirmModal.vue with Transition from the parent component, like this:
<Transition
enter-from-class="opacity-0"
enter-to-class="opacity-100"
leave-from-class="opacity-100"
leave-to-class="opacity-0"
>
<ConfirmModal
v-if="showConfirmModal"
title="Suppression"
text="Êtes-vous sûr de vouloir supprimer cet article ?"
#cancel="handleHideConfirmModal"
/>
</Transition>
I don't understand why I have to do this and why in this exemple the person doesn't need to do that though, they use Transition from inside the child component and the transition works fine
It's also not ideal because every time I use this component I will have to think to wrap it inside this transition for it to fully work
It's probably caused by the use of different versions of Vue.
Your question is tagged vuejs3, so you are very likely using Vue 3, but, in the example you linked, vue version 2.6.4 is being used.
In vue 3, at least, you must use the directives v-if or v-show in the root element inside the Transition component for it to trigger the changes whenever the root component inside appears and disappears.
you can read more about transitions here

Vue refs undefined in modal

I do have a for loop and inside i want to have a modal for each image
<div class="col pb-3" v-for="(item, index ) in img" :key="index" style="width: 300px;height:auto;">
<img v-b-modal="'modal-'+index" :ref="'image'" #mouseover="mouseOver" #mouseleave="mouseOut" /><br>
<b-modal :id="'modal-'+index" title="BootstrapVue">
<p class="my-4">Hello from modal - {{index}}</p>
<img :ref="'imagex'" />
</b-modal>
<div class="progress pt-2 mt-1" style="width: 100px;margin: 0 auto;">
<div class="progress-bar " :style="[{'width':width[index]+'px'}]" role="progressbar"
aria-valuenow="0" ref="'progress'" aria-valuemin="0" aria-valuemax="100"></div>
</div>
</div>
In methods i am giving src value to each image that has :ref="'image'" and i can actually give a src to them its work fine but, i also want be able to give src value images in modal. Its called :ref="'imagex'" but its undefined.
this.$refs.image[i].src = event.target.result //works
this.$refs.imagex[i].src = event.target.result //undefined
What is the problem an is there anyway to solve it ?
When used on elements/components with v-for, the registered reference will be an Array containing DOM nodes or component instances.
An important note about the ref registration timing: because the refs themselves are created as a result of the render function, you cannot access them on the initial render - they don’t exist yet! $refs is also non-reactive, therefore you should not attempt to use it in templates for data-binding.
.
can use it in events and only at mounted function.
https://v2.vuejs.org/v2/api/#ref

v-on:click not working - dynamically added html element

I am trying to get all images for a category using Vue
<div class="col-md-12 col-sm-2 p-2">
<a v-on:click="onCategoryManageImageClick($event)" data-target="#location-
category-images">
</span>
</a>
</div>
So the event onCategoryManageImageClick ($event) does not work, if I am adding a html block and then click on get image button.
this is index.js
methods:{
onImagesTabClick(){
this.$root.$emit('activated-tab:location-images');
},
onCategoriesTabClick(){
window.j1App.eventBus.$emit("j1-location-image-list:shown");
},
onCategoryManageImageClick: function(event) {console.log('working event..');
event.preventDefault();
window.j1App.eventBus.$emit("j1-location-category-image-
list:shown",event.currentTarget.id);
}
}
So basically it need to to work like we do in jQuery
$(document).on('click',function{
})
So it works either page load or if adding any new html element on DOM. same I want in Vue.
You cannot alter the Vue template outside of Vue. That won't work. Vue compiles the template once when starting up and adds the event listeners to the rendered elements. If you add elements afterwards, Vue will not know about them.
The correct way of doing this would be to add those new elements in Vue.
<div
class="col-md-12 col-sm-2 p-2"
v-for="item in items"
:key="item.id"
>
<a
v-on:click="onCategoryManageImageClick($event, item)"
data-target="#location-category-images"
>
</a>
</div>
See https://v2.vuejs.org/v2/guide/list.html for documentation. In this case you need the items array variable in data and add more array elements to it, if you need more links.
Try raplacing your a tag with p
<div class="col-md-12 col-sm-2 p-2">
<p v-on:click="onCategoryManageImageClick" data-target="#location-
category-images">
</p>
</div>

Vuejs and Slick Carousel - problem with v-for can't add element in carousel

I'm using vue-slick component but I have some problem with the v-for loop.
This is my code:
<slick
ref="slick"
:options="slickOptions"
class="float-left full-width slider-ingredients">
<div
v-for="ingredient in available_prots_source"
:key="ingredient.id"
#click="onSelectIngredient(ingredient.id, 'prots')"
class="slider-ingredient-item">
<div class="float-left ingredient-image">
<div class="content">
<img :src="ingredient.image" width="200" height="200" class="float-left cover-fit">
</div>
</div>
<h4 class="float-left full-width text-center ingredient-name">
{{ingredient.name}}
</h4>
<span class="float-left full-width text-center ingredient-details">
dettagli
</span>
</div>
</slick>
The problem is that my div is added outside the slick container. If I add a <div> just after the <slick> opening tag it render correctly but sees just one element even if my v-for add 4 or 5 elements.
What am I doing wrong?
How can I use slick with v-for loops?
from the official README (see method reInit in the README.md
// Helpful if you have to deal with v-for to update dynamic lists
this.$nextTick(() => {
this.$refs.slick.reSlick();
});