Build a Movie App with VueJS
Last Updated :
13 May, 2024
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">×</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:
Similar Reads
Build a Movie APP Using Next.js We will create a movie database app using Next.js and an external movie API (such as The Movie Database API). The app will enable users to view movies, search for specific movies, and view detailed information about each movie, including the title, release date, rating, brief description, and a list
7 min read
Build a Music app using VueJS We'll guide you through the process of building a music player application using Vue.js, a popular JavaScript framework for building user interfaces. The application will allow users to play, pause, and skip through a collection of songs, as well as view and select songs from a library. Preview Prer
9 min read
Building a Shopping List with VueJS The following approach covers how to build a simple shopping list app with VueJs. Vue (or Vue.js) is an open-source JavaScript framework geared towards building user interfaces, it was created by Evan You.Prerequisites:Basic understanding of HTML.Basic knowledge of CSSBasic knowledge of JavaScriptIn
3 min read
Build a Todo List App using VueJS This article provides an in-depth exploration of creating a Todo List application using Vue.js. It covers various aspects of building the application, whether you're new to Vue.js or looking to expand your skills, this comprehensive guide offers valuable insights and practical instructions to help y
4 min read
How to Setup VideoJS with VueJS? Video.js is a popular javascript library that allows support for various video playback formats on the web. With it, we can embed and customize our video components in our web pages that are made in various frontend frameworks like, Vue.js, React, Angular, etc. In this article, we will learn how to
2 min read
Movie Web Application with ReactJS React Movie APP is a movie web application project that involves creating components to display a list of movies and details about each movie along with a search functionality. Preview Image of Final Output:Approach for React Movie AppTo create the movie web application in React we will be using an
7 min read
Movie App Using Angular We will be creating a Movie Search Engine using Angular. This application allows users to search for movies by entering keywords and fetching and displaying a list of movie results in card format. The search engine initially loads a default set of movies to showcase the functionality. Through this p
5 min read
Create an Image Gallery App with Vue.js In this tutorial, we'll walk through the process of building an image gallery application using Vue.js. We'll explore different approaches to displaying images and provide the complete executable code for each one of them. Table of Content Using Vue components to create the galleryUsing Vue CDN to c
3 min read
How to Integrate Vite with Vue.js? Vite provides the flexibility and speed needed for modern web development by offering a fast-build tool and development server. Integrating Vite with Vue.js allows developers to use Viteâs efficient hot module replacement and optimized build processes while working with Vue's reactive framework. Thi
3 min read