Advent of JavaScript, Day 9
Challenge #9 an image carousel:
With the project files downloaded and codesandbox
‘d into a live CodeSandbox, I’m ready to get going!
User Requirements
Again, let’s start with the User Requirements and speculate how I can solve these:
- toggle left and right through the image thumbnails
Alrighty, this seems simple:
currentIndex
is the index of the current image to replace.feature
- Event handlers on
.left
and.right
to decrement and increment, respectively,currentIndex
- click an image to select it manually
This will set the currentIndex
to the index of the clicked image.
Wiring it Up
With Vue, this should all be a cinch!
Id like to use transitions, since a quick Google shows that the out-in
may work to make this seamless:
https://vuejs.org/v2/guide/transitions.html#Transition-Modes
However, probably not if I’m replacing elements vs. hidding/showing different ones. I’m going to skip transitions for now…
-
Adding Vue, as usual:
<script src="https://unpkg.com/vue@next"></script>
I find wiring up the markup first helps clarify the most semantic API before I start writing imperative (i.e. JavaScript) code.
-
Making
.feature
reactive:<div class="feature"> <img :src="'images/' + currentImage.image" alt="Featured" /> <div class="caption">{{ currentImage.caption }}</div> </div>
-
Making
.thumbnails
reactive:I wanted to make sure the thumbnails continued to scroll into view as
.left
and.right
were clicked. Vue has aref
attribute that allows you to reference an element from the template, just like React:https://v3.vuejs.org/guide/migration/array-refs.html#migration-strategy
<div class="thumbnails"> <ul> <li v-for="(item, index) in content" :class="{ selected: index === currentIndex }" :ref="setThumbnailRef" > <a @click.prevent="currentIndex = index" href="#"> <img :src="'images/' + item.image" :alt="'Thumbnail of ' + item.caption" /> </a> </li> </ul> </div>
-
Making
.left
and.right
reactive:I modeled this after the
window.history.go(delta)
API:<a @click.prevent="go(-1)" href="#" class="left"> <img src="./images/chevron.svg" alt="" /> </a> <a @click.prevent="go(+1)" href="#" class="right"> <img src="./images/chevron.svg" alt="" /> </a>
Demo
I think I need to try something different than Vue for the next one(s). Vue is making things too easy…