cari
Rumahhujung hadapan webtutorial jsKlon Netflix untuk Meningkatkan Kemahiran Bahagian Hadapan Anda

Netflix Clone to Level Up Your Frontend Skills

As a developer primarily focused on backend, I've always felt that my frontend skills could use some polishing. To test this, I decided to challenge myself by building a Netflix clone using Vue.js 3 and Vite. In this article, I'll break down the project structure, key components, and share my learning experience.

Project Overview

The goal was to create a responsive web application that mimics the core features of Netflix's user interface. Here's what I initially set out to build:

  • A homepage with multiple rows of movies, categorized by genre
  • Smooth horizontal scrolling for movie rows
  • Lazy loading of images for better performance
  • A search functionality to find movies

More to be added in the future.

Tech Stack

For this project, I chose the following tools:

  • Vue.js 3: For its reactivity system and component-based architecture
  • Vite: As a fast build tool and development server
  • Vue Router: For handling navigation
  • Pinia: For state management
  • Axios: For making API requests to TMDB
  • @vueuse/motion: For adding smooth animations

Project Structure

Here's an overview of the project structure:

netflix-clone/
├── src/
│   ├── components/
│   │   ├── MovieCard.vue
│   │   ├── MovieList.vue
│   │   ├── MovieRow.vue
│   │   └── NavBar.vue
│   ├── views/
│   │   ├── HomeView.vue
│   │   ├── MovieDetailView.vue
│   │   └── SearchView.vue
│   ├── router/
│   │   └── index.js
│   ├── services/
│   │   └── tmdb.js
│   ├── stores/
│   │   └── movies.js
│   ├── App.vue
│   └── main.js
├── .env.example
├── vite.config.js
└── package.json

Key Components Breakdown

MovieCard.vue

This component represents an individual movie. It displays the movie poster and, on hover, shows additional information like the title, rating, and release year.

<template>
  <div class="movie-card">
    <img class="{  lazy" src="/static/imghwm/default1.png" data-src="posterUrl" : :alt="Klon Netflix untuk Meningkatkan Kemahiran Bahagian Hadapan Anda" true :loaded imageloaded>
    <div v-if="isHovered" class="movie-info">
      <h3 id="Klon-Netflix-untuk-Meningkatkan-Kemahiran-Bahagian-Hadapan-Anda">{{ Klon Netflix untuk Meningkatkan Kemahiran Bahagian Hadapan Anda }}</h3>
      <p>Rating: {{ movie.vote_average }}/10</p>
      <p>{{ releaseYear }}</p>
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';

const props = defineProps(['movie']);
const imageLoaded = ref(false);
const isHovered = ref(false);

const posterUrl = computed(() => `https://image.tmdb.org/t/p/w500${props.movie.poster_path}`);
const releaseYear = computed(() => new Date(props.movie.release_date).getFullYear());

// ... hover logic
</script>

Key learnings:

  • Using computed properties for derived data
  • Implementing hover effects with CSS transitions
  • Lazy loading images for better performance

MovieRow.vue

This component creates a horizontally scrollable row of movies, typically grouped by genre.

<template>
  <div class="movie-row">
    <h2 id="title">{{ title }}</h2>
    <div class="movie-list" ref="movieList">
      <moviecard v-for="movie in movies" :key="movie.id" :movie="movie"></moviecard>
    </div>
    <button class="scroll-btn left">
    <button class="scroll-btn right">></button>
  </button>
</div>
</template>

<script setup>
import { ref } from 'vue';
import MovieCard from './MovieCard.vue';

const props = defineProps(['title', 'movies']);
const movieList = ref(null);

const scroll = (direction) => {
  const scrollAmount = direction === 'left' ? -300 : 300;
  movieList.value.scrollBy({ left: scrollAmount, behavior: 'smooth' });
};
</script>

### tmdb.js (API Service)

This service handles all API calls to The Movie Database (TMDB) using Axios.
import axios from 'axios';

const API_KEY = import.meta.env.VITE_TMDB_API_KEY;
const BASE_URL = 'https://api.themoviedb.org/3';

const tmdbApi = axios.create({
  baseURL: BASE_URL,
  params: { api_key: API_KEY },
});

export const getTrending = () => tmdbApi.get('/trending/all/week');
export const getMoviesByGenre = (genreId) => tmdbApi.get('/discover/movie', { params: { with_genres: genreId } });
export const searchMovies = (query) => tmdbApi.get('/search/movie', { params: { query } });

NavBar.vue

The NavBar component provides navigation for the application and includes a search input for finding movies.

<template>
  <nav class="navbar">
    <router-link to="/" class="navbar-brand">NetflixClone</router-link>
    <div class="navbar-links">
      <router-link to="/">Home</router-link>
      <div class="search-container">
        <input v-model="searchQuery" placeholder="Search movies...">
      </div>
    </div>
  </nav>
</template>

<script setup>
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import debounce from 'lodash/debounce';

const router = useRouter();
const searchQuery = ref('');

const debounceSearch = debounce(() => {
  if (searchQuery.value) {
    router.push({ name: 'search', query: { q: searchQuery.value } });
  }
}, 300);
</script>

HomeView.vue

The HomeView component serves as the main page of the application, displaying multiple MovieRow components with different genres.

<template>
  <div class="home-view">
    <movierow title="Trending" :movies="trendingMovies"></movierow>
    <movierow v-for="genre in genres" :key="genre.id" :title="genre.name" :movies="moviesByGenre[genre.id]"></movierow>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import MovieRow from '@/components/MovieRow.vue';
import { getTrending, getGenres, getMoviesByGenre } from '@/services/tmdb';

const trendingMovies = ref([]);
const genres = ref([]);
const moviesByGenre = ref({});

onMounted(async () => {
  const [trendingResponse, genresResponse] = await Promise.all([
    getTrending(),
    getGenres()
  ]);

  trendingMovies.value = trendingResponse.data.results;
  genres.value = genresResponse.data.genres.slice(0, 5); // Limit to 5 genres for this example

  for (const genre of genres.value) {
    const response = await getMoviesByGenre(genre.id);
    moviesByGenre.value[genre.id] = response.data.results;
  }
});
</script>

SearchView.vue

The SearchView component displays search results based on the user's query.

<template>
  <div class="search-view">
    <h2 id="Search-Results-for-searchQuery">Search Results for "{{ searchQuery }}"</h2>
    <div class="search-results">
      <moviecard v-for="movie in searchResults" :key="movie.id" :movie="movie"></moviecard>
    </div>
  </div>
</template>

<script setup>
import { ref, watch } from 'vue';
import { useRoute } from 'vue-router';
import MovieCard from '@/components/MovieCard.vue';
import { searchMovies } from '@/services/tmdb';

const route = useRoute();
const searchQuery = ref('');
const searchResults = ref([]);

const performSearch = async () => {
  const response = await searchMovies(searchQuery.value);
  searchResults.value = response.data.results;
};

watch(() => route.query.q, (newQuery) => {
  searchQuery.value = newQuery;
  performSearch();
}, { immediate: true });
</script>

You can find the full source code for this project on GitHub.

Atas ialah kandungan terperinci Klon Netflix untuk Meningkatkan Kemahiran Bahagian Hadapan Anda. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Ganti aksara rentetan dalam javascriptGanti aksara rentetan dalam javascriptMar 11, 2025 am 12:07 AM

Penjelasan terperinci mengenai kaedah penggantian rentetan javascript dan Soalan Lazim Artikel ini akan meneroka dua cara untuk menggantikan watak rentetan dalam JavaScript: Kod JavaScript dalaman dan HTML dalaman untuk laman web. Ganti rentetan di dalam kod JavaScript Cara yang paling langsung ialah menggunakan kaedah pengganti (): str = str.replace ("cari", "ganti"); Kaedah ini hanya menggantikan perlawanan pertama. Untuk menggantikan semua perlawanan, gunakan ungkapan biasa dan tambahkan bendera global g: str = str.replace (/fi

Bina Aplikasi Web Ajax anda sendiriBina Aplikasi Web Ajax anda sendiriMar 09, 2025 am 12:11 AM

Jadi di sini anda, bersedia untuk mempelajari semua perkara ini yang dipanggil Ajax. Tetapi, apa sebenarnya? Istilah Ajax merujuk kepada kumpulan teknologi longgar yang digunakan untuk membuat kandungan web yang dinamik dan interaktif. Istilah Ajax, yang asalnya dicipta oleh Jesse J

Bagaimana saya membuat dan menerbitkan perpustakaan JavaScript saya sendiri?Bagaimana saya membuat dan menerbitkan perpustakaan JavaScript saya sendiri?Mar 18, 2025 pm 03:12 PM

Artikel membincangkan membuat, menerbitkan, dan mengekalkan perpustakaan JavaScript, memberi tumpuan kepada perancangan, pembangunan, ujian, dokumentasi, dan strategi promosi.

Bagaimanakah saya mengoptimumkan kod JavaScript untuk prestasi dalam penyemak imbas?Bagaimanakah saya mengoptimumkan kod JavaScript untuk prestasi dalam penyemak imbas?Mar 18, 2025 pm 03:14 PM

Artikel ini membincangkan strategi untuk mengoptimumkan prestasi JavaScript dalam pelayar, memberi tumpuan kepada mengurangkan masa pelaksanaan dan meminimumkan kesan pada kelajuan beban halaman.

Bagaimanakah saya boleh debug kod javascript dengan berkesan menggunakan alat pemaju pelayar?Bagaimanakah saya boleh debug kod javascript dengan berkesan menggunakan alat pemaju pelayar?Mar 18, 2025 pm 03:16 PM

Artikel ini membincangkan debugging JavaScript yang berkesan menggunakan alat pemaju pelayar, memberi tumpuan kepada menetapkan titik putus, menggunakan konsol, dan menganalisis prestasi.

kesan matriks jQuerykesan matriks jQueryMar 10, 2025 am 12:52 AM

Bawa kesan filem matriks ke halaman anda! Ini adalah plugin jQuery yang sejuk berdasarkan filem terkenal "The Matrix". Plugin mensimulasikan kesan aksara hijau klasik dalam filem, dan hanya pilih gambar dan plugin akan mengubahnya menjadi gambar gaya matriks yang diisi dengan aksara angka. Datang dan cuba, sangat menarik! Bagaimana ia berfungsi Plugin memuat imej ke kanvas dan membaca nilai piksel dan warna: data = ctx.getimagedata (x, y, settings.grainsize, settings.grainsize) .data Plugin dengan bijak membaca kawasan segi empat tepat gambar dan menggunakan jQuery untuk mengira warna purata setiap kawasan. Kemudian, gunakan

Cara Membina Slider JQuery MudahCara Membina Slider JQuery MudahMar 11, 2025 am 12:19 AM

Artikel ini akan membimbing anda untuk membuat karusel gambar mudah menggunakan perpustakaan jQuery. Kami akan menggunakan perpustakaan BXSlider, yang dibina di atas jQuery dan menyediakan banyak pilihan konfigurasi untuk menubuhkan karusel. Pada masa kini, Gambar Carousel telah menjadi ciri yang mesti ada di laman web - satu gambar lebih baik daripada seribu perkataan! Selepas membuat keputusan untuk menggunakan karusel gambar, soalan seterusnya adalah bagaimana untuk menciptanya. Pertama, anda perlu mengumpul gambar-gambar resolusi tinggi yang berkualiti tinggi. Seterusnya, anda perlu membuat karusel gambar menggunakan HTML dan beberapa kod JavaScript. Terdapat banyak perpustakaan di web yang dapat membantu anda membuat karusel dengan cara yang berbeza. Kami akan menggunakan Perpustakaan BXSlider Sumber Terbuka. Perpustakaan BXSlider menyokong reka bentuk responsif, jadi karusel yang dibina dengan perpustakaan ini dapat disesuaikan dengan mana -mana

Cara memuat naik dan memuat turun fail CSV dengan sudutCara memuat naik dan memuat turun fail CSV dengan sudutMar 10, 2025 am 01:01 AM

Set data sangat penting dalam membina model API dan pelbagai proses perniagaan. Inilah sebabnya mengapa mengimport dan mengeksport CSV adalah fungsi yang sering diperlukan. Dalam tutorial ini, anda akan belajar cara memuat turun dan mengimport fail CSV dalam sudut

See all articles

Alat AI Hot

Undresser.AI Undress

Undresser.AI Undress

Apl berkuasa AI untuk mencipta foto bogel yang realistik

AI Clothes Remover

AI Clothes Remover

Alat AI dalam talian untuk mengeluarkan pakaian daripada foto.

Undress AI Tool

Undress AI Tool

Gambar buka pakaian secara percuma

Clothoff.io

Clothoff.io

Penyingkiran pakaian AI

AI Hentai Generator

AI Hentai Generator

Menjana ai hentai secara percuma.

Artikel Panas

R.E.P.O. Kristal tenaga dijelaskan dan apa yang mereka lakukan (kristal kuning)
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Tetapan grafik terbaik
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Cara Memperbaiki Audio Jika anda tidak dapat mendengar sesiapa
3 minggu yang laluBy尊渡假赌尊渡假赌尊渡假赌

Alat panas

SublimeText3 versi Mac

SublimeText3 versi Mac

Perisian penyuntingan kod peringkat Tuhan (SublimeText3)

Dreamweaver Mac版

Dreamweaver Mac版

Alat pembangunan web visual

PhpStorm versi Mac

PhpStorm versi Mac

Alat pembangunan bersepadu PHP profesional terkini (2018.2.1).

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

Persekitaran pembangunan bersepadu PHP yang berkuasa

SublimeText3 versi Cina

SublimeText3 versi Cina

Versi Cina, sangat mudah digunakan