Node App:如何创建 Netflix 克隆版。使用 HTML、CSS、JS 进行 Netflix 克隆。
视频教程
代码
您可能觉得有用的文章
AWS GenAI 直播!
大家好,今天我们将学习如何仅使用 HTML、CSS 和 JS 轻松创建 Netflix 克隆版本,无需其他库。我们还将使用 TMDB API 从其数据库中获取真实数据。
Netflix Clone,我们日常生活中都使用Netflix。如果你刚开始接触Web开发,这个项目可以成为你一个很好的练习项目。这个Netflix Clone是一个动态网站,拥有你进行全栈开发实践所需的一切。它运行在Node.js服务器上,并使用TMDB API处理所有数据。
特征
- 看起来与 Netflix 相似。
- 动态站点在 Node.js 服务器上运行。
- 所有数据均来自 TMDB API。
- 专用动态电影信息页面。
- 有电影预告片和推荐。
- 具有流畅的卡片滑块效果。
如果您想观看演示或完整的编码教程视频,可以观看下面的教程。
视频教程
如果您能订阅我的 YouTube 频道来支持我,我将不胜感激。
因此,不要浪费更多时间,让我们看看如何编写代码。
代码
由于这是一个 node.js web 应用,我们需要 NPM 和 Node.js 才能启动,因此请确保您的系统中已安装它们。
那么让我们从它的文件夹结构开始吧。
文件夹结构。
这是我们的文件夹结构。
NPM 初始化
让我们从初始化 NPM 开始。在public
文件夹外部,在你的root
目录中,打开命令提示符或终端。然后执行。npm init
它会询问你一些详细信息。你可以按 Enter 键获取默认的项目详细信息。执行后,npm init
你应该会看到一个package.json
文件。
很好,现在安装创建服务器所需的一些库。
安装库
创建package.json
文件后。运行此命令。
npm i express.js nodemon
i
- 表示安装。express.js
- 是我们创建服务器所需的库。nodemon
- 是一个允许您即使在对服务器进行更改后也能无缝运行服务器的库。
安装完成后,您应该能够在目录node_modules
中看到文件夹root
。
现在package.json
用文本编辑器打开文件,并进行一些编辑。
服务器.js
编辑后在目录中package.json
创建 JS 文件。server.js
root
并将其写入server.js
。
const express = require('express');
const path = require('path');
let initial_path = path.join(__dirname, "public");
let app = express();
app.use(express.static(initial_path));
app.get('/', (req, res) => {
res.sendFile(path.join(initial_path, "index.html"));
})
app.listen(3000, () => {
console.log('listening on port 3000......');
})
解释
在顶部,我们使用require
方法导入库,以便我们可以在此文件中使用它。我们导入了两个库express
和path
。
path
库用于跟踪路径。
导入库完成后,我们将设置一个app
等于 的变量express()
,这样所有与服务器相关的功能都可以添加到我们的app
变量中。此外,我们还设置了initial_path
一个 ,用于保存public
文件夹路径。
之后,我们有app.use()
一个用作中间件的函数,它express.static()
允许我们设置静态目录路径。在本例中,我们将public
文件夹设置为静态路径,因为我们的HTML
文件就在该文件夹中。
app.get('/')
是一个监听器,在本例中,它监听的是指向GET
我们根/
路径的请求。每当我们收到任何GET
请求时/
,我们都会向其提供index.html
文件。这就是我们res.sendFile()
要做的。
我们的最后一块server.js
是app.listen
用于添加服务器监听端口的。在本例中,我们将其设置为3000
。这样我们的服务器将在 上运行localhost:3000
,而不是其他任何端口。
现在,在终端或 cmd 提示符下运行npm start
以下命令启动服务器。然后,打开浏览器localhost:3000
。您将能够看到index.html
文件。
到目前为止,我们已经创建了服务器并成功地将index.html
文件提供给/
路径。
那么我们来做一些前端工作吧。现在
主页。
因此对于我们的主页,我们将使用这些文件。index.html
,,,,。style.css
home.js
api.js
scroll.js
让我们从index.html
文件开始。先输入基本的 HTML 结构。然后是链接style.css
文件。首先,我们来创建导航栏。
<!-- navbar -->
<nav class="navbar">
<img src="img/logo.png" class="logo" alt="">
<div class="join-box">
<p class="join-msg">unlimited tv shows & movies</p>
<button class="btn join-btn">join now</button>
<button class="btn">sign in</button>
</div>
</nav>
确保您的服务器正在运行,如果没有,则
npm start
在您的终端中运行。
输出
我将用到的所有 CSS 属性都很容易理解。所以我只会解释 JS 部分。如果您对任何部分有任何疑问,即使是 CSS 部分,也欢迎在讨论中问我。
现在设置导航栏的样式
*{
margin: 0;
padding: 0;
box-sizing: border-box;
}
body{
width: 100%;
position: relative;
background: #181818;
font-family: 'roboto', sans-serif;
}
.navbar{
width: 100%;
height: 60px;
position: fixed;
top: 0;
z-index: 9;
background: #000;
padding: 0 2.5vw;
display: flex;
align-items: center;
}
.logo{
height: 60%;
}
.join-box{
width: fit-content;
display: flex;
justify-content: center;
align-items: center;
height: auto;
margin-left: auto;
}
.join-msg{
color: #fff;
text-transform: uppercase;
}
.btn{
border: 1px solid #fff;
border-radius: 2px;
background: none;
color: #fff;
height: 35px;
padding: 0 10px;
margin-left: 10px;
text-transform: uppercase;
cursor: pointer;
}
.join-btn{
background: #dd0e15;
border-color: #dd0e15;
}
输出
<!-- main section -->
<header class="main">
<h1 class="heading">movies</h1>
<p class="info">Movies move us like nothing else can, whether they're scary, funny, dramatic, romantic or anywhere in-between. So many titles, so much to experience.</p>
</header>
并设计它
.main{
position: relative;
margin-top: 60px;
width: 100%;
padding: 40px 2.5vw;
color: #fff;
}
.heading{
text-transform: capitalize;
font-weight: 900;
font-size: 50px;
}
.info{
width: 50%;
font-size: 20px;
margin-top: 10px;
}
我们必须在.main
元素内部创建一个电影列表元素,它将保存相同类型的电影。
<div class="movie-list">
<button class="pre-btn"><img src="img/pre.png" alt=""></button>
<h1 class="movie-category">Popular movie</h1>
<div class="movie-container">
<div class="movie">
<img src="img/poster.jpg" alt="">
<p class="movie-title">movie name</p>
</div>
</div>
<button class="nxt-btn"><img src="img/nxt.png" alt=""></button>
</div>
你可以看到,我们创建了它们,pre-btn
并且nxt-btn
它们之间也包含一个movie-card
元素。好吧,我们将使用 JS 创建电影卡片和列表元素,但出于样式方面的考虑,我们在这里只创建了一个卡片。这只是为了方便 CSS 使用。
.movie-list{
width: 100%;
height: 250px;
margin-top: 40px;
position: relative;
}
.movie-category{
font-size: 20px;
font-weight: 500;
margin-bottom: 20px;
text-transform: capitalize;
}
.movie-container{
width: 100%;
height: 200px;
display: flex;
align-items: center;
overflow-x: auto;
overflow-y: hidden;
scroll-behavior: smooth;
}
.movie-container::-webkit-scrollbar{
display: none;
}
.movie{
flex: 0 0 auto;
width: 24%;
height: 200px;
text-align: center;
margin-right: 10px;
cursor: pointer;
position: relative;
}
.movie img{
width: 100%;
height: 170px;
object-fit: cover;
}
.movie p{
text-transform: capitalize;
height: 20px;
overflow: hidden;
}
.pre-btn,
.nxt-btn{
position: absolute;
height: 200px;
top: 50%;
transform: translateY(-50%);
width: 2.5vw;
background: #181818;
border: none;
outline: none;
opacity: 0;
}
.pre-btn{
left: -2.5vw;
}
.nxt-btn{
right: -2.5vw;
}
.pre-btn img,
.nxt-btn img{
width: 20px;
height: 20px;
object-fit: contain;
}
.nxt-btn:hover,
.pre-btn:hover{
opacity: 1;
}
输出
一旦我们完成了卡片的造型,我们就可以提交它们。
<header class="main">
<h1 class="heading">movies</h1>
<p class="info">Movies move us like nothing else can, whether they're scary, funny, dramatic, romantic or anywhere in-between. So many titles, so much to experience.</p>
<!-- movie list -->
<!-- <div class="movie-list">
<button class="pre-btn"><img src="img/pre.png" alt=""></button>
<h1 class="movie-category">Popular movie</h1>
<div class="movie-container">
<div class="movie">
<img src="img/poster.jpg" alt="">
<p class="movie-title">movie name</p>
</div>
</div>
<button class="nxt-btn"><img src="img/nxt.png" alt=""></button>
</div> -->
</header>
我们的main
版块应该看起来像这样。主页部分已经完成了。
现在将所有 JS 文件添加到index.html
文件中。因为我们现在需要它们。
<script src="js/api.js"></script>
<script src="js/scroll.js"></script>
<script src="js/home.js"></script>
确保按照完全相同的顺序添加这些文件。
现在前往TMDB 官方网站创建 API 密钥。如果您不知道如何创建,请观看此视频。
创建 API 密钥后将其粘贴到api.js
文件中
api.js
let api_key = "your api key";
然后前往TMDB 文档。找到以下三个 HTTP 链接。
api.js
let api_key = "your api key";
let img_url = "https://image.tmdb.org/t/p/w500";
let genres_list_http = "https://api.themoviedb.org/3/genre/movie/list?";
let movie_genres_http = "https://api.themoviedb.org/3/discover/movie?";
img_url
- 用于获取图片。因为我们会获取电影图片的路径 ID。例如,如果我们获取的图片 ID 为,123
则图片 URL 为https://image.tmdb.org/t/p/w500/123
genres_list_http
- 用于获取电影类型列表,这样我们就不必手动获取不同类型的电影。movie_genres_http
- 是获取具有相同类型的电影。
完成这些 HTTPS 后,打开home.js
文件。
home.js
fetch(genres_list_http + new URLSearchParams({
api_key: api_key
}))
.then(res => res.json())
.then(data => {
data.genres.forEach(item => {
fetchMoviesListByGenres(item.id, item.name);
})
});
解释
在这里,我们使用了在文件中声明fetch
的方法。并用于向链接添加参数。获取 res 后,我们将其转换为 JSON ,转换为 JSON 后,我们得到了获取的数据。在理解我们在做什么之前,首先看一下获取的数据结构。genres_list_http
api.js
new URLSearchParams
api_key
res.json()
这样就理解了数据结构。现在明白了获取 JSON 数据后我们在做什么。
data.genres.forEach(item => {
fetchMoviesListByGenres(item.id, item.name);
})
由于我们有一个包含各种类型的数组,因此我们使用方法循环遍历每个类型forEach
。并在其中调用fetchMoviesListByGenres(id, genres)
我们接下来要创建的方法。
现在获取具有不同类型的电影。
const fetchMoviesListByGenres = (id, genres) => {
fetch(movie_genres_http + new URLSearchParams({
api_key: api_key,
with_genres: id,
page: Math.floor(Math.random() * 3) + 1
}))
.then(res => res.json())
.then(data => {
makeCategoryElement(`${genres}_movies`, data.results);
})
.catch(err => console.log(err));
}
解释
在这里我们做同样的事情,我们正在获取数据,但在这种情况下,我们正在发出请求movie_genres_http
并添加更多参数。paramwith_genres
将为我们提供仅具有该类型的电影,例如,如果我们的类型 id 为喜剧电影,那么我们只会得到喜剧电影。parampage
将提供我们想要的结果,在这种情况下,我们使用它Math.random()
来获取一些随机的电影结果页面。
获取数据后,我们执行相同的res.json()
操作将其转换为 JSON。调用makeCategoryElement(category, data)
该函数将创建影片类别。同样,如果您愿意,也可以通过控制台记录数据结构。
现在创建电影类别。但在此之前,请main
从 HTML 中选择我们的元素。
const main = document.querySelector('.main');
const makeCategoryElement = (category, data) => {
main.innerHTML += `
<div class="movie-list">
<button class="pre-btn"><img src="img/pre.png" alt=""></button>
<h1 class="movie-category">${category.split("_").join(" ")}</h1>
<div class="movie-container" id="${category}">
</div>
<button class="nxt-btn"><img src="img/nxt.png" alt=""></button>
</div>
`;
makeCards(category, data);
}
解释
在这个函数中,我们有两个参数,一个是category
,另一个是data
。所以我们函数做的第一件事就是使用 向我们的元素添加一个.movie-list
元素。如果你还记得我们在 HTML 文件中创建的代码,但最后注释掉了,请复制并粘贴到这里。确保使用not ,因为我们不想重写它的 HTML。main
innerHTML
+=
=
<h1 class="movie-category">${category.split("_").join(" ")}</h1>
如果你看到这行代码,首先,我们使用了 JS 模板字符串,如果不使用,你将无法像这样写。这里我们有一个h1
元素,我们将它的文本设置为我们在函数开始时获取的类别。但我们也在这里执行了一些方法。让我们详细看看它们。
例如,假设类别等于喜剧。
<h1 class="movie-category">${category}</h1>
那么输出将是 - comdey_movies。但我们不想,_
这就是我们拆分它的原因。<h1 class="movie-category">${category.split("_")}</h1>
那么它将无法工作,因为现在我们有一个数组 ["comedy", "movies"]。这就是为什么要使用join
方法来连接数组。<h1 class="movie-category">${category.split("_").join(" ")}</h1>
那么输出将是 - 喜剧电影
我希望你明白这一点。
然后我们为元素设置一个唯一的 ID,movie-container
以便稍后添加卡片。最后,我们调用makeCards(category, data)
该函数在电影容器元素内创建卡片。
现在创建一张卡片。
const makeCards = (id, data) => {
const movieContainer = document.getElementById(id);
data.forEach((item, i) => {
})
}
解释
在这个函数中,我们使用从上面函数获取的数据,在开始时选择影片容器元素id
。之后,我们循环遍历data
usingforEach
方法。在方法内部,我们检查一些条件。
if(item.backdrop_path == null){
item.backdrop_path = item.poster_path;
if(item.backdrop_path == null){
return;
}
}
这个条件是检查,如果我们的结果集里没有电影backdrop
图片路径,就把它设置poster_path
为“否”。别搞砸了。有时 TMDB 电影的数据里没有图片路径,所以我们会检查它。
之后我们有
movieContainer.innerHTML += `
<div class="movie" onclick="location.href = '/${item.id}'">
<img src="${img_url}${item.backdrop_path}" alt="">
<p class="movie-title">${item.title}</p>
</div>
`;
这里,我们使用了该innerHTML
方法来附加一开始就已经创建好的卡片 HTML 结构。同样,这里我们也使用了模板字符串。如果您看到我们有onclick
一个事件到movie-card
元素,我们将使用该事件location.href
将用户重定向到我们接下来要创建的电影页面。
if(i == data.length - 1){
setTimeout(() => {
setupScrolling();
}, 100);
}
这是检查最后一次施法。卡片创建完成后,我们将运行setupScrolling()
函数来设置滑块效果。我们也必须创建这个。
写完这么多 JS 代码,现在我们可以看到输出了,没有任何错误。
输出
但是我们还没有创建滑块效果写入。对于那个打开的scroll.js
文件。
scroll.js
const setupScrolling = () => {
const conainter = [...document.querySelectorAll('.movie-container')];
const nxtBtn = [...document.querySelectorAll('.nxt-btn')];
const preBtn = [...document.querySelectorAll('.pre-btn')];
}
解释
querySelectorAll
首先,在这个函数中,我们使用方法选择我们的容器、下一个按钮和上一个按钮。
选择它们后,在函数内部输入以下内容。
conainter.forEach((item, i) => {
let containerDimensions = item.getBoundingClientRect();
let containerWidth = containerDimensions.width;
})
这里我们循环遍历每个容器元素。并使用getBoundingClientRect
方法获取容器的尺寸。最后将其存储containerDimensions.width
(当然,这会给出容器的宽度)到containerWidth
。
之后在这个 for 循环中添加这个。
nxtBtn[i].addEventListener('click', () => {
item.scrollLeft += containerWidth;
})
preBtn[i].addEventListener('click', () => {
item.scrollLeft -= containerWidth;
}
这里我们选择nxtBtn
带有preBtn
容器索引的元素,并为其添加点击事件。此外,还进行了一些简单的数学运算。
此后我们应该能够获得滑块效果。
我们的主页已经完成。
服务器.js
现在我们需要在关于页面中添加一些代码server.js
。
在之前输入这些代码app.listen()
;
app.get('/:id', (req, res) => {
res.sendFile(path.join(initial_path, "about.html"));
})
app.use((req, res) => {
res.json("404");
})
这里,我们为路径添加了 GET 请求监听器/:id
。这意味着任何前面带有单斜杠的路径都会执行代码。它适用于/123
,但不适用于/123/12/1
。最后,我们app.use()
再次使用 which 作为中间件,这意味着如果请求路径与上述路径不同,则执行此操作。这意味着404
消息。
此后,您将能够通过点击电影卡片将自己重定向到电影详细信息页面。
关于页面
让我们创建最后一个页面。为了避免编写大量的 CSS,我们可以使用链接about.css
和文件。style.css
然后将导航栏复制粘贴到这里。之后创建 movie-info 元素
关于.html
<!-- movie info -->
<div class="movie-info">
<div class="movie-detail">
<h1 class="movie-name">Movie Name</h1>
<p class="genres">Comedy</p>
<p class="des">Lorem ipsum dolor sit amet consectetur, adipisicing elit. In commodi incidunt odit inventore suscipit, debitis officia modi exercitationem animi nemo.</p>
<p class="starring"><span>Starring:</span></p>
</div>
</div>
并进行造型。
.movie-info{
width: 100%;
height: calc(100vh - 60px);
margin-top: 60px;
background-size: cover;
background-repeat: no-repeat;
}
.movie-detail{
width: 50%;
height: 100%;
background: rgb(24, 24, 24);
background: linear-gradient(90deg, rgba(24, 24, 24, 1), rgba(24, 24, 24, 0) 100%);
padding: 5vw;
display: flex;
flex-direction: column;
justify-content: flex-end;
color: #fff;
}
.movie-name{
font-size: 30px;
font-weight: 500;
}
.genres{
opacity: 0.6;
margin: 30px 0;
}
.des{
width: 70%;
line-height: 20px;
margin-bottom: 30px;
}
.starring span{
opacity: 0.6;
}
输出
CSS 完成后,您可以从信息元素中删除所有文本,使其完全为空。
<h1 class="movie-name"></h1>
<p class="genres"></p>
<p class="des"></p>
<p class="starring"><span>Starring:</span></p>
像这样。
现在创建视频推荐。
<div class="trailer-container">
<h1 class="heading">Video Clip</h1>
<iframe src="" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
你应该注意到了iframe
。这有点难理解,所以我建议你看一下这个视频预告片,以便更好地理解。Style
It。
.trailer-container,
.recommendations{
color: #fff;
padding: 5vw 5vw 0;
}
.heading{
font-size: 30px;
font-weight: 300;
margin-bottom: 20px;
}
iframe{
width: 400px;
height: 200px;
}
在输出中,除了电影信息元素和视频剪辑文本外,我们什么也看不到。因为我们的iframe
源是空的。
现在创建推荐容器。
<div class="recommendations">
<h1 class="heading">More Like This</h1>
<div class="recommendations-container">
<div class="movie">
<img src="img/poster.jpg" alt="">
<p class="movie-title">movie name</p>
</div>
</div>
</div>
CSS
.recommendations-container{
width: 100%;
display: flex;
flex-wrap: wrap;
}
.movie p{
position: absolute;
bottom: 30px;
width: 100%;
height: 30px;
line-height: 30px;
background: rgba(0, 0, 0, 0.5);
text-align: center;
opacity: 0;
}
.movie:hover p{
opacity: 1;
}
输出
我们已经完成了样式设置。您可以对.movie
元素进行注释。这与我们在主页中创建的元素相同。
也向此页面添加脚本。记住,添加顺序完全相同。
<script src="js/api.js"></script>
<script src="js/about.js"></script>
现在打开api.js
文件。并添加以下内容。
let original_img_url = "https://image.tmdb.org/t/p/original";
let movie_detail_http = "https://api.themoviedb.org/3/movie";
您可以从 TMDB 文档中找到这些 HTTP。original_img_url
- 这是为了获取原始分辨率的电影图像。movie_detail_http
- 这是为了获取特定电影的详细信息。
现在打开about.js
。然后写下这个。
let movie_id = location.pathname;
您location.pathname
将能够从 URL 中提取电影 ID。例如,如果 URL 是,localhost:3000/123
则这将返回/123
我们的电影 ID。
之后使用相同的fetch
方法获取电影详细信息,并将获取的数据传递给名为的函数setupMovieInfo(data)
。
// fetching movie details
fetch(`${movie_detail_http}${movie_id}?` + new URLSearchParams({
api_key: api_key
}))
.then(res => res.json())
.then(data => {
setupMovieInfo(data);
})
让我们创造吧setupMovieInfo
。
const setupMovieInfo = (data) => {
const movieName = document.querySelector('.movie-name');
const genres = document.querySelector('.genres');
const des = document.querySelector('.des');
const title = document.querySelector('title');
const backdrop = document.querySelector('.movie-info');
title.innerHTML = movieName.innerHTML = data.title;
genres.innerHTML = `${data.release_date.split('-')[0]} | `;
for(let i = 0; i < data.genres.length; i++){
genres.innerHTML += data.genres[i].name + formatString(i, data.genres.length);
}
if(data.adult == true){
genres.innerHTML += ' | +18';
}
if(data.backdrop_path == null){
data.backdrop_path = data.poster_path;
}
des.innerHTML = data.overview.substring(0, 200) + '...';
backdrop.style.backgroundImage = `url(${original_img_url}${data.backdrop_path})`;
}
解释
这个函数非常简单,首先它会选择所有元素,例如电影名称、标题标签、描述和类型。选择所有元素后,我们使用innerHTML
方法设置值。但对于类型,我们有一些条件,例如,首先我们通过一些格式化操作只添加上映年份。之后,我们循环遍历电影数据中包含的所有类型,并将它们添加到类型中,并进行一些格式化。是的,您可以看到formatString
函数,让我们来创建它。
const formatString = (currentIndex, maxIndex) => {
return (currentIndex == maxIndex - 1) ? '' : ', ';
}
backdrop_path
类型之后,我们会像之前在主页上检查的那样进行检查。并将图片设置为背景图片。
由于我们没有获取电影详情中的演员信息,因此必须单独获取。
//fetching cast info
fetch(`${movie_detail_http}${movie_id}/credits?` + new URLSearchParams({
api_key: api_key
}))
.then(res => res.json())
.then(data => {
const cast = document.querySelector('.starring');
for(let i = 0; i < 5; i++){
cast.innerHTML += data.cast[i].name + formatString(i, 5);
}
})
我觉得这很容易理解。如果你有疑问,可以在讨论中问我。
现在如果我们看到输出。
输出
现在让我们获取视频片段。
/ fetching video clips
fetch(`${movie_detail_http}${movie_id}/videos?` + new URLSearchParams({
api_key: api_key
}))
.then(res => res.json())
.then(data => {
let trailerContainer = document.querySelector('.trailer-container');
let maxClips = (data.results.length > 4) ? 4 : data.results.length;
for(let i = 0; i < maxClips; i++){
trailerContainer.innerHTML += `
<iframe src="https://youtube.com/embed/${data.results[i].key}" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
`;
}
})
这里,我们获取与电影相关的视频详情。获取结果后,我们会检查要设置的条件maxClips
,因为我们最多需要 4 个片段。之后,我们会循环maxClips
播放。创建一个Iframe
与 HTML 文件中相同的结构。将其从 HTML 文件中复制到 HTML 文件中。但请注意它的src
属性。
输出
现在最后一件事是提出建议。
// fetch recommendations
fetch(`${movie_detail_http}${movie_id}/recommendations?` + new URLSearchParams({
api_key: api_key
}))
.then(res => res.json())
.then(data => {
let container = document.querySelector('.recommendations-container');
for(let i = 0; i < 16; i++){
if(data.results[i].backdrop_path == null){
i++;
}
container.innerHTML += `
<div class="movie" onclick="location.href = '/${data.results[i].id}'">
<img src="${img_url}${data.results[i].backdrop_path}" alt="">
<p class="movie-title">${data.results[i].title}</p>
</div>
`;
}
})
项目的最后一步,我们从 TMDB 中获取类似的电影。获取数据后,我们只制作了 16 张卡片。这与我们之前在 中创建卡片的方法非常相似home.js
。
输出
我们完成了。
好了,就是这样。希望你理解了所有内容。如果你有疑问或者我遗漏了什么,请在评论区告诉我。
您可能觉得有用的文章
如果你能订阅我的YouTube频道,我将不胜感激。我创作了精彩的网络内容。订阅吧
感谢您的阅读。
文章来源:https://dev.to/themodernweb/how-to-create-netflix-clone-netflix-clone-with-hmtl-css-js-989