Why carousel does not work when using v-for in img, vuejs? - vue.js

I am currently using the following library: https://www.npmjs.com/package/vue-owl-carousel.
It turns out that when using v-for in img inside the carousel, the carousel does not work, correctly.
This way it doesn't work:
<carousel
:autoplay="true"
:loop="true"
:center="true"
:nav="false"
:margin="5"
>
<img
v-for="item in detIncidente.fotos"
:key="item.fecha"
:src="item.path"
width="446"
height="446"
#click="showSingle(item.path)"
/>
</carousel>
This way if it works correctly for me:
<carousel
:autoplay="true"
:loop="true"
:center="true"
:nav="false"
:margin="5"
>
<img width="446" height="669" src="https://placeimg.com/200/200/any?3" />
<img width="446" height="669" src="https://placeimg.com/200/200/any?4" />
<img width="446" height="669" src="https://placeimg.com/200/200/any?2" />
<img width="446" height="669" src="https://placeimg.com/200/200/any?3" />
</carousel>

If you load the images dynamically, the carousel component doesn't wait until data is loaded.
You can try adding v-if
v-if="detIncidente && detIncidente.fotos && detIncidente.fotos.length"
Full code
<carousel
v-if="detIncidente && detIncidente.fotos && detIncidente.fotos.length"
:autoplay="true"
:loop="true"
:center="true"
:nav="false"
:margin="5"
>
<img
v-for="item in detIncidente.fotos"
:key="item.fecha"
:src="item.path"
width="446"
height="446"
#click="showSingle(item.path)"
/>
</carousel>

Related

Handling button in multiple Cards

I've product listing page where I use multiple ProductCard component. I need to add Spinner to Add to cart button when clicking on it, but if I just add Spinner to v-else I've Spinners in every ProductCard. How to control only this ProductCard where I click Add to cart button?
Parent's component:
<ProductCard
v-for="product in products"
:key="product.id"
:product="product"
/>
Child's component:
<template>
<div id="productCart">
<div>
<NuxtLink :to="`/product/${item.slug}`" />
<NuxtLink v-if="item.name" :to="`/product/${item.slug}`">
<h5
id="productName"
v-text="item.name"
/>
</NuxtLink>
<Button
v-if="!loading"
#click="addToBuyCart({ product: item })"
v-text="$t('labels.buy')"
/>
<Spinner v-else />
</div>
</div>
</template>
loading is defined in composable, and it's updating in addToBuyCart function by making it true, then adding to cart (api), then making it false
As pointed by IVO, in such situations you should check against a value specific for each item in the loop, item ID for example, instead of a boolean which lacks specificity and therefore cannot be used for such scenarios.
<template>
<div id="productCart">
<div>
<NuxtLink :to="`/product/${item.slug}`" />
<NuxtLink v-if="item.name" :to="`/product/${item.slug}`">
<h5
id="productName"
v-text="item.name"
/>
</NuxtLink>
<Button
v-if="loading !== item.id"
#click="addToBuyCart({ product: item })"
v-text="$t('labels.buy')"
/>
<Spinner v-else />
</div>
</div>
</template>
const addToBuyCart = ({product}) => {
loading = product.id
// some logic or request
loading = null
}

custom navigation for q-carousel not working

I am struggling solving my navigation q-carousel that I want, it is does not work.
It just shows default navigation only but not the custom one that I grab the code from the Quasar website.
My template:
<q-card-section class="q-pa-none" >
<div style="width:60%; padding-bottom: 250px"
class="bg-transparent text-center q-gutter-y-lg absolute-center ">
<q-carousel
animated
v-model="slide"
arrows
navigation
infinite
control-type="flat"
control-color="secondary"
class="bg-transparent text-center">
>
<template v-slot:navigation-icon="{ active, btnProps, onClick }">
<q-btn v-if="active" size="lg" icon="home" color="yellow" flat round dense #click="onClick" />
<q-btn v-else size="sm" :icon="btnProps.icon" color="white" flat round dense #click="onClick" />
</template>
<q-carousel-slide :name="1" >1</q-carousel-slide>
<q-carousel-slide :name="2">2</q-carousel-slide>
<q-carousel-slide :name="3">3</q-carousel-slide>
</q-carousel>
</q-card-section>
My script:
export default {
data() {
return {
slide : 1,
}
}
}
Your code is actually working, but you kind of mixed opening and closing tags.
There is no open tag for </q-card-section>
There is no closing tag for your leading <div>
The below code should work for you:
<div
style="width: 60%; padding-bottom: 250px"
class="bg-transparent text-center q-gutter-y-lg absolute-center"
>
<q-carousel
animated
v-model="slide"
arrows
navigation
infinite
control-type="flat"
control-color="secondary"
class="bg-transparent text-center"
>
<template v-slot:navigation-icon="{ active, btnProps, onClick }">
<q-btn
v-if="active"
size="lg"
icon="home"
color="yellow"
flat
round
dense
#click="onClick"
/>
<q-btn
v-else
size="sm"
:icon="btnProps.icon"
color="white"
flat
round
dense
#click="onClick"
/>
</template>
<q-carousel-slide :name="1">1</q-carousel-slide>
<q-carousel-slide :name="2">2</q-carousel-slide>
<q-carousel-slide :name="3">3</q-carousel-slide>
</q-carousel>
</div>
You should consider setting up auto formatting in your code editor/IDE to auto format your source code, if you are using VS Code you can do this quite easily: https://stackoverflow.com/a/29973358/13765033
This way, you shouldn't run into such trouble again (it also helps Stack Overflow users to read your source code).

Manage undefined value of an object

I'm using Vue 3 and I want to show an image depending on the value of an object
So I have something like:
<img
v-if="results.object.value === 'test'"
src="#/assets/images/services/img.svg"
class="w-60"
alt=""
/>
<img
v-else-if="results.object.value === 'test2'"
src="#/assets/images/services/img2.svg"
class="w-80"
alt=""
/>
So this works correctly but sometimes the results.object.value is undefined and it throws an error in the console:
[Vue warn]: Error in render: "TypeError: Cannot read property 'value'
of undefined"
So I try to add another v-if to show other image if the value is undefined:
<img
v-else-if="!results.object.value"
src="#/assets/images/services/test3.svg"
class="w-40"
alt=""
/>
But I still get the same error. How can I manage it?
The problem is results.object is possibly undefined, so you should verify it exists before trying to access a subproperty. You could do this easily by wrapping both img elements with a <template v-if="results.object">. And you could show a fallback img, using an <img v-else>, adjacent to this template:
<template v-if="results.object">
<img
v-if="results.object.value === 'test'"
src="#/assets/images/services/img.svg"
class="w-60"
alt=""
/>
<img
v-else-if="results.object.value === 'test2'"
src="#/assets/images/services/img2.svg"
class="w-80"
alt=""
/>
</template>
<!-- show fallback img if no `results.object` -->
<img
v-else
src="#/assets/images/services/test3.svg"
class="w-80"
alt=""
/>
You can use optional chaining like:
results?.object?.value??'default'==='test'
or
just results?.object?.value === 'test'
<img
v-if="results?.object?.value === 'test'"
src="#/assets/images/services/img.svg"
class="w-60"
alt=""
/>
<img
v-else-if="results?.object?.value === 'test2'"
src="#/assets/images/services/img2.svg"
class="w-80"
alt=""
/>
<img
v-else-if="!results?.object?.value"
src="#/assets/images/services/test3.svg"
class="w-40"
alt=""
/>

How to build images which are dynamically sourced by npm run build command in vue.js?

I have some images inside src/assets/ and in one of my component
i have this
<img
src="/src/assets/guna.jpg"
alt="Guna"
class="w-12 h-12 rounded-full"
/>
and also this :
<img
:src="`src/assets/${image}`"
alt=""
class="w-12 h-12 rounded-full"
/>
here i have bind image and passes image name in a loop and i have array of image in data which i loop in
Now when i run npm run build , only top one image that is guna.jpg is buld and get copied in dist/assets/.......jpg but not images which are bind
so how i solve it ?
you have to use require
<img
:src="require(`src/assets/${image}`)"
alt=""
class="w-12 h-12 rounded-full"
/>

Vue-Owl-Carousel not working when using Loop

Vue-Owl-Carousel workign fine using the basic model :
<carousel>
<img src="https://placeimg.com/200/200/any?1">
<img src="https://placeimg.com/200/200/any?2">
<img src="https://placeimg.com/200/200/any?3">
<img src="https://placeimg.com/200/200/any?4">
</carousel>
But when i use a loop on , the Carousel broke and shows all slides in column.
<carousel> // Not Working
<img v-for="slide in slides" :src="getslide(slide)">
</carousel>
<carousel> // Not Working
<template v-for="slide in slides"><img :src="getslide(slide)"></template>
</carousel>
<carousel> // Not Working, the error is with v-for..
<img v-for="slide in slides" src="/slide.png">
</carousel>
Thank you if you can help.
You can try:
<div v-if="slides.length > 0">
<carousel>
<img v-for="slide in slides" :src="getslide(slide)">
</carousel>
</div
Are you using axios to get data to the slides array from the database?. If so the template of vue is being rendered before the data is received in the array causing the carousel not to work. you can re render the vue component and it will work. I had same problem and re-rendering the vue solved it.
<div v-if="slides.length > 0">
<carousel>
<img v-for="slide in slides" :src="getslide(slide)">
</carousel>
</div
code worked for me :)
I had the same problem, just check if your slides data is true
try this code :
<carousel v-if="slides">
<img v-for="slide in slides" :src="slide.png">
</carousel>