DEV Community

loading...

Quick & Easy Vue.js Search Facility

chrisdixon161 profile image Chris Dixon Originally published at blog.chrisdixon.io Updated on ・4 min read

Adding a search facility to your project can be complex, but only if you need it to be. Sometimes, we just need a simple filter, and return the results.

This post is going to show you how to do this in Vue.js, but the same principle can be applied to React or almost anything else.

I am going to create a simple blog style app, with a search input to filter the posts by the post's content.

You can find the finished demo app here:

Easy Vue.js Search on codesandbox

And a video version on YouTube here:
https://youtu.be/mCl5LxO5FEc

To follow along, you can either use Codesandbox, and create a new project with a Vue.js starter, or use the Vue-CLI to create a new project.

Easy Vue.js Search on codesandbox

This is how the starter looks in codesandbox.

Remove HelloWorld.vue from the components folder, and clean up the App.vue to look like this:

// App.vue
<template>
  <div id="app"></div>
</template>

<script>
export default {
  name: "App",
  components: {}
};
</script>

<style>
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

In the components folder, create a new file called Post.vue, and add our basic Vue.js structure:

// components/Post.vue
<template>
  <article>
    hi
  </article>
</template>

<script>
export default {};
</script>

Next, to include the post into our app we need to register it, which I will do in the App.vue:

// App.vue
<template>
  <div id="app">
    // 3. output component
    <post></post>
  </div>
</template>

<script>
// 1. import component 
import Post from "./components/Post";

export default {
  name: "App",
  // 2. register component
  components: { Post }
};
</script>

The browser should now show our message of "hi".

We now need some sample blog posts to work with and display in the Post.vue component, for this example I will add some content into the App.vue "data" property:

// App.vue
<script>
import Post from "./components/Post";

export default {
  name: "App",
  components: { Post },
  data() {
    return {
      // add blog posts array:
      posts: [
        {
          id: 1,
          title: "Post 1",
          body: "Vue.js is cool"
        },
        {
          id: 2,
          title: "Post 2",
          body: "Javascript is cool"
        }
      ]
    };
  }
};
</script>

We now have 2 sample posts and with Vue.js, we can loop through each post and display the "Post" component:

// App.vue
<template>
  <div id="app">
    <div v-for="post in posts" :key="post.id">
      <post></post>
    </div>
  </div>
</template>

We should now see the "hi" message twice in the browser. This makes sense since we have 2 blog posts.

However, we want to pass the blog post data to the Post.vue component, and we do this via props:

// App.vue- add props to post:
<post :post="post"></post>

Back over in the Post.vue, we receive these props (note prop validation is skipped for simplicity):

// components/Post.vue

<script>
export default {
  props: ["post"]
};
</script>

And we can modify the template to output the blog title and body:

// components/Post.vue
<template>
  <article>
    <h3>{{ post.title }}</h3>
    <p>{{post.body}}</p>
  </article>
</template>

And we should now see the posts display in the browser!

But what about the filter? Let' begin with an input box to type in, inside of the App.vue:

//App.vue
<template>
  <div id="app">
    // add input:
    <input type="text" v-model="search">
    <div v-for="post in posts" :key="post.id">
      <post :post="post"></post>
    </div>
  </div>
</template>

Notice here we are using v-model, this is to create 2 way data binding with a data property called search, so we also need to add this to our data property:

  // App.vue
  ...

  data() {
    return {
      search: "",

 ...

This search property will now hold the value typed into the input field by the user.

We now need to get all blog posts, filter them using this search term, and return the new blog posts.

To do this, I will use a computed property. This will be ideal to re-calculate the matching blog posts each time the input is updated:

// App.vue- final script section:

<script>
import Post from "./components/Post";

export default {
  name: "App",
  components: {
    Post
  },
  data() {
    return {
      search: "",
      posts: [
        {
          id: 1,
          title: "Post 1",
          body: "Vue.js is cool"
        },
        {
          id: 2,
          title: "Post 2",
          body: "Javascript is cool"
        }
      ]
    };
  },
  // Add computed section:
  computed: {
    filteredPosts() {
      return this.posts.filter(post =>
        post.body.toLowerCase().includes(this.search.toLowerCase())
      );
    }
  }
};
</script>

Here we are filtering the blog posts, and returning only the values which includes the search term.

This search is matching any letter, word, phrase in the blog post body section. To make the search as inclusive as possible, we also make it case insensitive by lower casing all text.

The final thing to do is to loop through this "filteredPosts" computed value, rather than all posts:

// App.js
...

<div v-for="post in filteredPosts" :key="post.id">
  <post :post="post"></post>
</div>


...

And thats it! Go ahead and give this a test in the browser.

And now you can type into the input field, and only return blog posts which match...

Discussion (5)

Collapse
dthompsondev profile image
Danny Thompson

This was awesome Chris!

Collapse
chrisdixon161 profile image
Chris Dixon Author

Thanks Danny!

Collapse
sanchezdav profile image
David Sanchez

That was so easy! Thanks for sharing!

Collapse
chrisdixon161 profile image
Chris Dixon Author

Thanks David!

Collapse
justicemashunye profile image
justice mashunye

Perfect,couldnt do anything but to share it on twitter,facebook and followed you on social media, and considered of buying the course,but i didnt understand the discount thing

Forem Open with the Forem app