Closed richgcook closed 1 year ago
Hi @richgcook,
Please not that as I mentioned, my experience with Vue is very limited. So if any seasoned Vue dev stumbles upon this issue they should feel free to chip in.
Thank you for your question. I found this StackOverflow thread that explains how to listen for prop changes:
watch(() => props.slides, () => {
emblaApi.value?.reInit()
});
Maybe that's what you're looking for?
I would recommend you to use the embla-carousel-vue
package because it does some of the heavy lifting for you:
options
and plugins
, for example by declaring them as refs
and reassign them, the carousel instance will reInit()
automatically when options and/or plugins change.Let me know if it helps.
Best, David
Thanks so much, @davidjerleke
What's strange is that using that code snippet, which I've used previously, never fires.
I'll definitely switch to embla-carousel-vue and go from there but it's bizarre but appreciate you don't have much experience in vue... just thought there would be more out there with the same issue.
@richgcook thank you for the additional details. People seem to run this problem every now and then so I'm going to consider creating a feature request suggesting to add this feature to all the framework/library wrappers. I'll let you know how it goes.
In the meantime, you might find some help if you ask this question on StackOverflow or Reddit. Additionally, if you don't mind, you can drop a CodeSandbox with your setup demonstrating the problem here in this issue.
Best, David
Hi again @richgcook,
If you add the following code to your setup, does it work as expected?
const observer = new MutationObserver((mutations) => {
const childMutations = mutations.filter((mutation) => {
if (mutation.type !== "childList") return false;
return mutation.addedNodes.length || mutation.removedNodes.length;
});
if (childMutations.length) emblaApi.value.reInit();
});
observer.observe(emblaApi.value.containerNode(), { childList: true });
If yes, I might add it to all library/framework wrappers including embla-carousel-vue
.
Best, David
Hi @davidjerleke thanks for your help and support on this.
Unfortunately this doesn't seem to help. observer
doesn't return anything. I'm assuming this is for the onMounted method but do let me know!
@richgcook thank you for trying. The following is working with React and Svelte: Both wrappers are picking up when the slides are mapped from props and when the slide props change. They also successfully pick up any added/removed slides.
At this stage I think that there's something unexpected/funky going on with your setup.
I'm assuming this is for the onMounted method but do let me know!
Yes, like this:
<script>
import { onMounted } from "vue";
import emblaCarouselVue from "embla-carousel-vue";
export default {
setup() {
const [emblaNode, emblaApi] = emblaCarouselVue({ loop: false });
onMounted(() => {
if (emblaApi.value) {
const observer = new MutationObserver((mutations) => {
const childMutations = mutations.filter((mutation) => {
if (mutation.type !== "childList") return false;
return mutation.addedNodes.length || mutation.removedNodes.length;
});
if (childMutations.length) emblaApi.value.reInit();
});
observer.observe(emblaApi.value.containerNode(), { childList: true });
}
});
return { emblaNode, emblaApi };
},
};
</script>
What happens if you change:
<script setup>
...into:
<script>
?
If that doesn't work, I suggest that you to create a reduced CodeSandbox with your setup that demonstrates the problem. With the sandbox, it will be way easier to debug and see why this is happening. Because I'm blindly guessing here when there could be literally anything causing this when I don't have your setup available. Thanks!
Best, David
@richgcook any news on this?
Hi @davidjerleke apologies greatly for the delay.
I'm using the <script setup></script>
sugar for vue but nevertheless I couldn't get your suggested fix to work. I'll try to create a CodeSandbox asap.
Hi @davidjerleke sorry I'm struggling for time to get a CodeSandbox box. Apologies. I've been doing some tests, however.
Within onMounted
I've fired the init event with the internalEngine() method to see what it was returning between a browser refresh and an internal route (when it doesn't work unless resized).
embla.value.on('init', () => {
console.log(embla.value.internalEngine())
})
We can see from the screenshot that the scrollSnaps
and containerRect
are returning 0 as well as the limit
returning NaN.
Just thought I'd share in case you have any thoughts...
Hi @richgcook,
Thank you for the additional details.
We can see from the screenshot that the
scrollSnaps
andcontainerRect
are returning 0 as well as the limit returning NaN.
Yes, it tells me that by the time Embla carousel is initialized, there are no slides for Embla to pick up inside its container. Ifg you get the time to create a CodeSandbox demonstrating the problem, I'll debug it further.
Best, David
Hi @richgcook,
I'm closing this until there's a reduced test case that clearly demonstrates the problem (a CodeSandbox or similar). Because I can't debug fragments of code that are shared in comments.
Thank you for understanding.
Best, David
Bug is related to
Embla Carousel version
Describe the bug
Within my nuxt3 application on load the embla carousel works fine but when navigation away and back (using NuxtLink, for example) the slider looks initialised but you cannot swipe/drag/use the slider. If I resize the browser it works as usual again.
I have read about using the reInit() method on other issues but having tried watching embla or scrollSnaps etc it doesn't seem to work.
I have also tried the vue wrapper but get the same issue. Weirdly I never had this issue in nuxt2/vue2.
CodeSandbox