👋 Hello guys! Today, I completed the front-end coding with Vue3 to create a search function based on user-entered keywords. The keywords can be categories, tags, or any words from an array. Check out the image below.


Oh, certainly, I would like to demonstrate how I accomplished it on my blog.
The layout
First I developed my Vue component template using pure Tailwind CSS.
The search layout
<template>
<div class="relative">
<form >
<input
class="w-full border pr-12 pl-4 py-2 rounded-full focus:border-blue-500 focus:shadow-outline outline-none"
type="text"
v-model="searchVal"
placeholder="Search..."
/>
<div class="absolute right-0 inset-y-0 pr-3 flex items-center">
<svg
class="fill-current h-6 w-6 text-gray-400"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
>
<path
d="M12.9 14.32a8 8 0 1 1 1.41-1.41l5.35 5.33-1.42 1.42-5.33-5.34zM8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12z"
/>
</svg>
</div>
</form>
</div>
...
</div>
</template>
So explain … In the layout above l created a div with class=”relative” to be the father of absolute div that involves the icon search (SVG from heroicons). The input tag receives the v-model directive called “searchVal”. The “v-model” is often needed to sync the state of form input elements with the corresponding state.
Results and list keywords layout
For the following, I need to inform if my search has no results and create the template of search list results.
<template>
...
<p v-if="noResults">No results</p>
<ul class="divide-y">
<li v-if="results" class="p-2" v-for="keyword in keywordsFiltered">
<div class="flex justify-between">
<p class="text-sm">{{ keyword.title }}</p>
<a class="underline text-sm" :href="keyword.link">Go</a>
</div>
</li>
</ul>
</template>
As you see above, the template “result <p>” and “list <li>” have some Vue directives. The first one is the conditional v-if which will show the result of the “noResult” computed function. The <li..> tag v-if is only to show the list of words if “results” is true. The other one is the “v-for” loop directive to render a list of items based on an array.
The Javascript
The following code below shows the data with default initial values, the list of the array “keywords” which brings objects and their properties “title” and “link”.
The keywordsFiltered()
I used the JavaScript Array filter, to compare the array title matches with the searchVal
.
The noResults()
brings true
of false, if the keywordsFiltered()
match length equals 0.
If more than 2 words (here you can define the number you want, remembering the array starts with 0), when typing on input, shows the list of results, if less than 2 words it is hidden.
Here is the complete code. Enjoy!
<template>
<div class="relative">
<form >
<input
class="w-full border pr-12 pl-4 py-2 rounded-full focus:border-blue-500 focus:shadow-outline outline-none"
type="text"
v-model="searchVal"
placeholder="Search..."
/>
<div class="absolute right-0 inset-y-0 pr-3 flex items-center">
<svg
class="fill-current h-6 w-6 text-gray-400"
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 20 20"
>
<path
d="M12.9 14.32a8 8 0 1 1 1.41-1.41l5.35 5.33-1.42 1.42-5.33-5.34zM8 14A6 6 0 1 0 8 2a6 6 0 0 0 0 12z"
/>
</svg>
</div>
</form>
</div>
<p v-if="noResults">No results</p>
<ul class="divide-y">
<li v-if="results" class="p-2" v-for="keyword in keywordsFiltered">
<div class="flex justify-between">
<p class="text-sm">{{ keyword.title }}</p>
<a class="underline text-sm" :href="keyword.link">Go</a>
</div>
</li>
</ul>
</div>
</template>
<script>
export default {
name: "SearchForm",
data() {
return {
searchVal: "",
results: false,
keywords: [
{
title: "Lorem Ipsum",
link: "/lorem-ipsum",
},
{
title: "Dolor sit",
link: "/dolor-sit",
},
{
title: "amet",
link: "/amet",
},
{
title: "One fine day",
link: "/one-fine-day",
},
{
title: "Oncomming",
link: "/oncomming",
},
{
title: "One OFF",
link: "/one-off",
},
],
};
},
computed: {
noResults() {
return this.keywordsFiltered.length === 0;
},
keywordsFiltered() {
let searchTerm = this.searchVal;
let keywordsList = this.keywords.filter((keyword) => {
let match = keyword.title.toLowerCase().match(searchTerm.toLowerCase());
return match;
});
if (searchTerm.length > 1) {
this.results = true;
} else {
this.results = false;
}
return keywordsList;
},
},
};
</script>
That is all, see you next!