I've recently developed an Anime Search App using Vue.js and the new script setup. I'm currently struggling to access the search results in order to display the number of titles found. The app is fetching data from an external API, but it's displaying a fixed number for each result instead of the actual titles. Can someone guide me on how to correctly output the number of anime titles? I have limited experience with Vue and JavaScript overall, so any help would be greatly appreciated! Thank you!
Below is the code snippet for my search page:
<template>
<header>
<div class="img-scroll img">
<h1>Anime Search</h1>
</div>
</header>
<main class="animeSearch">
<form class="search-box" @submit.prevent="HandleSearch">
<input
type="search"
class="search-field"
placeholder="Search for an anime..."
required
v-model="search_query" />
</form>
<p>{{ resultCount }} results!</p>
<Swiper :slides-per-view="4" :space-between="50" class="cards" v-
if="animelist.length > 0">
<SwiperSlide class="card" v-for="anime in animelist"
:key="anime.mal_id"
:anime="anime">
<a :href="anime.url" target="_blank">
<img
:src="anime.image_url"
:alt="anime.title + ' Poster'"
/>
<h3>{{ anime.title }}</h3>
</a>
</SwiperSlide>
</Swiper>
<div class="no-results" v-else>
<h3>Type in an Anime and hit 'enter' for search results.<br>
Use your cursor to swipe through images.<br>
Click on the image for information about the anime.<br>
Happy searching!...</h3>
</div>
</main>
<footer>
<p>© Megan Louise 2022</p>
</footer>
</template>
<script>
import { ref } from 'vue';
import { Swiper, SwiperSlide } from "swiper/vue";
import { computed } from "vue";
import "swiper/css";
export default {
components: {
Swiper,
SwiperSlide,
},
setup() {
const onSwiper = (swiper) => {
console.log(swiper);
};
const search_query = ref("");
const animelist = ref([]);
const HandleSearch = async () => {
animelist.value = await fetch(`https://api.jikan.moe/v3/search/anime?
q=${search_query.value}`)
.then(res => res.json())
.then(data => data.results);
search_query.value = "";
};
const onSlideChange = () => {
console.log('slide change');
};
const resultCount = computed(() => {
return animelist.value.length;
console.log('resultCount');
});
return {
search_query,
animelist,
HandleSearch,
onSwiper,
resultCount,
onSlideChange
};
},
}
</script>
<style scoped>
input[type='search'] {
font-family: 'BIZ UDGothic', sans-serif;
background-color: black;
border: 2px solid #FD8721;
color: #FD8721;
width: 100%;
height: 40px;
padding: 5px;
max-width: 600px;
border-radius: 8px;
margin-bottom: 40px;
font-size: 22px;
}
h3 {
color: #ECC013;
text-shadow: 1px 1px #FD8721;
font-weight: 400;
}
.cards {
display: flex;
flex-wrap: wrap;
margin: 10px 40px;
justify-content: space-evenly;
cursor: pointer;
}
.card {
width: 100%;
max-width: 200px;
height: auto;
padding: 0px 8px;
margin-bottom: 16px;
}
img {
cursor: grab;
width: 100%;
height: 300px;
object-fit: cover;
border-radius: 16px;
box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.15);
transition: 0.4s;
border: 2px solid #BA1039;
}
img:hover {
transform: scale(1.05);
}
@media only screen and (max-width: 820px) {
h1 {
font-size: 3em;
}
}
</style>