<div v-cloak id="index">
<div class="">
<form action="/search" method="get">
<div class="input-group">
<input type="text" placeholder="Cerca prodotti..." name="s" @input="debounceSearch" class="form-control">
</div>
</div>
<span v-if="typing">You are typing</span>
<p>{{searchQuery}}</p>
</form>
<div v-if="searchResults">
<transition-group tag="ul" class="" name="list">
<li class="active-results" :key="result.id" v-for="(result, hindex) in searchResults">{{ result.title }}</li>
</transition-group>
</div>
</div>
[v-cloak] {
display: none;
}
[v-cloak] > * {
display: none;
}
[v-cloak]::before {
content: "loading…";
}
/* base */
.list {
backface-visibility: hidden;
z-index: 1;
}
/* moving */
.list-move {
transition: all 600ms ease-in-out 50ms;
}
/* appearing */
.list-enter-active {
transition: all 400ms ease-out;
}
/* disappearing */
.list-leave-active {
transition: all 200ms ease-in;
position: absolute;
z-index: 0;
}
/* appear at / disappear to */
.list-enter,
.list-leave-to {
opacity: 0;
}
new Vue({
el: "#index",
data: {
typing: null,
debounce: null,
searchQuery: null,
searchResults: null
},
watch: {
// whenever searchQuery changes, this function will run
searchQuery(newQuery, oldQuery) {
if (newQuery) {
this.searchResults = null;
fetch(`https://dummyjson.com/products/search?q=${newQuery}`)
.then((res) => res.json())
.then((data) => (this.searchResults = data.products));
} else {
this.searchResults = [];
}
}
},
methods: {
debounceSearch(e) {
this.typing = "You are typing";
this.searchResults = null
clearTimeout(this.debounce);
this.debounce = setTimeout(() => {
this.typing = null;
this.searchQuery = e.target.value;
}, 600);
}
}
});
This Pen doesn't use any external CSS resources.