@d3t-distribution/vue3-ssr-carousel

N.B: This repository is a fork of vue-ssr-carousel with some changes to make it work with Vue 3 and Nuxt 3.
Written from CoffeeScript/Pug/Stylus to JS/TS/SCSS.
A performance focused Vue 3/Nuxt 3 carousel designed for SSR/SSG environments. No JS is used to lay out the carousel or
its slides. The goal is to improve LCP and CLS scores because there is no layout or markup changes when JS hydrates.
It's primarily designed for rendering "card" style slides (like for linking to articles or products") where the carousel-ness
is conditionally applied based on the number of cards that are slotted in as well as the viewport width.
Check out the demo: https://vue3-ssr-carousel.netlify.app
Getting Started
yarn add @d3t-distribution/vue3-ssr-carousel
Default
// Import Vue and SsrCarousel from the source file.
import SsrCarousel from '../../src/ssr-carousel';
export default defineNuxtPlugin((nuxtApp) => {
// Register the 'ssr-carousel' component.
nuxtApp.vueApp.component('ssr-carousel', SsrCarousel);
});
Nuxt
// nuxt.config.js
export default {
buildModules: ['vue3-ssr-carousel/nuxt']
};
Usage
<ssr-carousel>
<div class="slide">Slide 1</div>
<div class="slide">Slide 2</div>
<div class="slide">Slide 3</div>
</ssr-carousel>
API
Props
Slots
| Slots |
Description |
default |
Where your slides get injected. |
back-arrow |
Replace the default back icon. Slot props: |
|
disabled - True if at first page when not looping. |
next-arrow |
Replace the default next icon. Slot props: |
|
disabled - True if at last page when not looping. |
dot |
Replace the default pagination dots. Slot props: |
|
index - The page index that the dot represents. |
|
disabled - True if dot represents current page. |
Methods
| Methods |
Description |
next() |
Go forward a page or slide, depending on the paginate-by-slide prop |
back() |
Go back a page or slide, depending on the paginate-by-slide prop |
goto(index) |
Go to an index. If paginate-by-slide is false, this equates to a page offset. If true, this equates to a slide offset. |
Events
| Events |
Description |
change({ index }) |
Fired when the internal index counter changes. |
update:modelValue |
Same as change but intended for use with v-model. |
press |
Fired on mouse or touch down. |
release |
Fired on mouse or touch up. |
drag:start |
Fired on start of dragging. |
drag:end |
Fired on end of dragging. |
tween:start({ index }) |
Fired when the carousel starts tweening to it's final position. |
tween:end({ index }) |
Fired when the carousel has finished tweening to it's destination. |
Why another carousel component
- Not a Vue component, so extra work building a Vue wrapper for it.
- No SSR support, delaying LCP scoring.
- When JS hydrates, the slides get nested in a new parent, which affects LCP calculations.
- Slick applies responsive rules only after JS inits. This also results in getting a
Mismatching childNodes vs. VNodes
error when the page hydrates at a viewport width that changes the slidesToShow.
- It's extra work to make the carousel look the same before and after Slick inits, since you have to style them two
different ways.
- Difficulty determining if there's overflow after Slick inits because when Slick is initialized and
infinite: true,
Slick adds a full set of .slick-cloned slides before the "real" slides, and another full set after them
- Doesn't handle being empty well.
- When using custom arrows or dots, it would show a warning that the Nodes do not match.
- Doesn't do a good job of preventing images and links within slides from preventing dragging.
Contribute
We invite you to contribute and help improve this repo 💚
Here are a few ways you can get involved:
- Reporting Bugs / Share suggestions: If you come across any bugs or have ideas to enhance the code, your are free
to create an issue or send
a pull-request.
Local Development
Installation
# Install dependencies and start dev server (http://localhost:3006)
yarn install && yarn dev
Tests
Run all
yarn ci:run
Open interface
yarn ci:open
License
MIT