Horje
Build a Movie App with VueJS

We will build a movie application using Vue.js. By the end, you’ll have a fully functional movie app that will allow users to search for movies, view their details, and get information such as title, year, rating, and plot.

Prerequisites:

Approach

  • Vue Components: We will create two Vue components, MovieSearch and MovieDetail.
  • HTTP Requests: Axios is used to make API calls to OMDB.
  • Conditional Rendering: We will implement conditional rendering to display search results or movie details based on user interactions.

Steps to Create Application

Step 1: Setup Vue Project

Create a new Vue project using Vue CLI.

vue create movie-mania

Step 2: Install Axios

Axios is used for making HTTP requests. Install it in your project.

npm install axios

Updated dependencies will look like

"dependencies": {
"axios": "^1.6.8",
"core-js": "^3.8.3",
"vue": "^3.2.13"
},

Step 3: Creating and managing files and folders

  • Create MovieDetail.vue and MovieSearch.vue files inside the component folder
  • Replace the content of src/App.vue with the given below code.

Example: This example shows the creation of a Movie App.

JavaScript
//App.vue

<template>
  <div class="App">
    <header class="App-header">
      <img src=
"https://media.geeksforgeeks.org/gfg-gg-logo.svg"
      alt="GeeksforGeeks Logo"
      class="logo" />
      <h1>Movie Mania</h1>
    </header>
    <main>
      <MovieSearch @searchInput="searchInput"
                     @search="search" />
      <div class="container">
        <div
          v-for="movie in filteredResults"
          :key="movie.imdbID"
          class="item"
          @click="openDetail(movie.imdbID)"
        >
          <img :src="movie.Poster" alt="Movie Poster" />
          <h3>{{ movie.Title }}</h3>
        </div>
      </div>
      <MovieDetail v-if="selected.Title"
                     :selected="selected" 
                     @closeDetail="closeDetail" />
    </main>
  </div>
</template>

<script>
import axios from "axios";
import MovieSearch from "./components/MovieSearch.vue";
import MovieDetail from "./components/MovieDetail.vue";

export default {
  name: "App",
  components: {
    MovieSearch,
    MovieDetail,
  },
  data() {
    return {
      s: "", // Initialize search query
      results: [], // Initialize results array
      selected: {}, // Initialize selected movie object
      apiurl: "https://www.omdbapi.com/?apikey=a2526df0",
    };
  },
  mounted() {
    // Fetch initial movies based on specific keywords
    this.fetchInitialMovies();
  },
  methods: {
    fetchInitialMovies() {
      // Keywords for initial movie search
      const keywords = ["hindi", "avengers", "comedy"];
      
      // Fetch movies for each keyword 
      // and combine the results
      Promise.all(keywords.map(keyword => {
        return axios(this.apiurl + "&s=" + keyword)
          .then(({ data }) => data.Search || [])
          .catch(error => {
            console.error("Error fetching movies:", error);
            return [];
          });
      })).then(results => {
        this.results = results.flat(); 
        // Combine arrays of movies
      });
    },
    searchInput(e) {
      this.s = e.target.value;
    },
    search(e) {
      if (e.key === "Enter") {
        axios(this.apiurl + "&s=" + this.s)
             .then(({ data }) => {
          this.results = data.Search || [];
        });
      }
    },
    openDetail(id) {
      axios(this.apiurl + "&i=" + id).then(({ data }) => {
        this.selected = data;
      });
    },
    closeDetail() {
      this.selected = {};
    },
  },
  computed: {
    filteredResults() {
      // Filter results based on search query
      return this.results.filter(movie => movie.Title.toLowerCase()
                                  .includes(this.s.toLowerCase()));
    }
  },
};
</script>



<style>
.App {
  text-align: center;
  background-color: #f4f4f4;
  min-height: 100vh;
}

.App-header {
  background-color: #333;
  color: white;
  padding: 20px 0;
  display: flex;
  justify-content: center;
  align-items: center;
}

.logo {
  width: 50px;
  margin-right: 10px;
}

.container {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 20px;
  padding: 20px;
}

.item {
  cursor: pointer;
  width: 200px;
  text-align: center;
  padding: 10px;
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  transition: transform 0.3s ease;
}

.item:hover {
  transform: translateY(-5px);
}

.item img {
  width: 100%;
  border-radius: 8px;
}

.MovieDetail {
  background-color: rgba(0, 0, 0, 0.8);
  color: white;
  padding: 20px;
  border-radius: 8px;
  max-width: 600px;
  margin: 20px auto;
}

.MovieDetail h2 {
  margin-top: 0;
}

.MovieDetail span {
  font-weight: bold;
}

.MovieDetail img {
  max-width: 100%;
  border-radius: 8px;
  margin-bottom: 20px;
}

.MovieDetail p {
  line-height: 1.5;
}

.close {
  background-color: #333;
  color: white;
  border: none;
  padding: 10px 20px;
  border-radius: 4px;
  cursor: pointer;
  transition: background-color 0.3s ease;
}

.close:hover {
  background-color: #555;
}

.search-bar {
  margin: 20px auto;
  max-width: 400px;
}

.search {
  width: 100%;
  padding: 10px;
  font-size: 16px;
  border: 1px solid #ddd;
  border-radius: 4px;
  box-sizing: border-box;
  transition: border-color 0.3s ease;
}

.search:focus {
  outline: none;
  border-color: #333;
}
</style>
JavaScript
//MovieSearch.vue

<template>
  <div class="search-bar">
    <input
      type="text"
      placeholder="Search for a Movie..."
      class="search"
      @input="searchInput"
      @keypress.enter="search"
    />
  </div>
</template>

<script>
export default {
  name: "MovieSearch",
  methods: {
    searchInput(e) {
      this.$emit("searchInput", e);
    },
    search(e) {
      this.$emit("search", e);
    },
  },
};
</script>

<style scoped>
.search-bar {
  margin: 20px auto;
  max-width: 400px;
}

.search {
  width: 100%;
  padding: 10px;
  font-size: 16px;
  border: 1px solid #ddd;
  border-radius: 4px;
  box-sizing: border-box;
  transition: border-color 0.3s ease;
}

.search:focus {
  outline: none;
  border-color: #333;
}
</style>
JavaScript
//MovieDetail.vue

<template>
  <div class="modal" 
         @click.self="closeDetail">
    <div class="modal-content">
      <span class="close"
              @click="closeDetail">&times;</span>
      <h2>{{ selected.Title }}</h2>
      <span>{{ selected.Year }}</span>
      <p class="rating">Rating: 
                  {{ selected.imdbRating }}</p>
      <div class="about">
        <img :src="selected.Poster" alt="Movie Poster" />
        <p>{{ selected.Plot }}</p>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "MovieDetail",
  props: {
    selected: Object,
  },
  methods: {
    closeDetail() {
      this.$emit("closeDetail");
    },
  },
};
</script>

<style scoped>
.modal {
  display: flex;
  align-items: center;
  justify-content: center;
  position: fixed;
  z-index: 999;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.5);
}

.modal-content {
  background-color: #fefefe;
  border-radius: 8px;
  padding: 20px;
  max-width: 600px;
  max-height: 80vh; 
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
}

.close {
  position: absolute;
  top: 10px;
  right: 10px;
  font-size: 20px;
  cursor: pointer;
}
</style>


Run the Project:

npm run dev

Output:




Reffered: https://www.geeksforgeeks.org


JavaScript

Related
JavaScript Program to Transform a BST to Greater Sum Tree JavaScript Program to Transform a BST to Greater Sum Tree
JavaScript Program to Count Distinct Elements in Every Window JavaScript Program to Count Distinct Elements in Every Window
JavaScript Program to Find Circular Rotation of an Array by K Positions JavaScript Program to Find Circular Rotation of an Array by K Positions
Reverse all the Words of Sentence JavaScript Reverse all the Words of Sentence JavaScript
JavaScript Program to Find the Next Power of Two JavaScript Program to Find the Next Power of Two

Type:
Geek
Category:
Coding
Sub Category:
Tutorial
Uploaded by:
Admin
Views:
20