使用React和Vite构建一个AirBnb Experiences克隆网站
这一篇文章中,我会教你如何做一个AirBnb Experiences的克隆网站。主要涵盖React中Props的使用。
克隆网站最终呈现的效果:

1. 使用vite构建基础框架
npm create vite@latestcd airbnb-project
npm install
npm run dev
2. 构建网站的3个部分
网站从上至下主要分为导航栏、简介和活动栏三个部分。
我们在public文件夹之下建立components文件夹,然后分别建立Navbar.jsx,Hero.jsx和Card.jsx这三个文件,分别对应网站的三个部分。
另外,在public文件夹之下建立images文件夹,包含网站要用的所有图片。

photo-grid.png

wedding-photography.png

mountain-bike.png

airbnb-logo.png

katie-zaferes.png

star.png
3. 删除index.css中的所有内容
index.css
* {box-sizing: border-box;
}body {margin: 0;font-family: 'Poppins', sans-serif;
}
4. 导航栏
Navbar.jsx
export default function Navbar() {return (<nav><img src="/images/airbnb-logo.png" className="nav--logo"/></nav>)
}
对应的index.css中的内容。
nav {height: 70px;display: flex;padding: 20px 36px;box-shadow: 0px 2.98256px 7.4564px rgba(0, 0, 0, 0.1);
}.nav--logo {max-width: 100px;
}
5. 简介栏
Hero.jsx
export default function Hero() {return (<section className="hero"><img src="/images/photo-grid.png" className="hero-photo" /><h1 className="hero-header">Online Experiences</h1><p className="hero--text">Join unique interactive activities led by one-of-a-kind hosts-all without leaving home.</p></section>)
}
对应的index.css中的内容。
section {padding: 20px;
}.hero {display: flex;flex-direction: column;
}.hero--photo {max-width: 400px;align-self: center;
}.hero--header {margin-bottom: 16px;
}.hero--text {margin-top: 0;
}
6. 活动栏
Card.jsx
export default function Card(props) {let badgeTextif (props.item.openSpots === 0){badgeText = "SOLD OUT"} else if (props.item.location === "Online"){badgeText = "ONLINE"}return (<div className="card">{badgeText && <div className="card--badge">{badgeText}</div>}<img src={`/images/${props.item.coverImg}` }className="card--image"alt="Image of Katie Zaferes."/><div className="card--stats"><img src="/images/star.png" className="card--star"alt="Star icon." /><span>{props.item.stats.rating}</span><span className="gray">({props.item.stats.reviewCount}) · </span><span className="gray">{props.item.location}</span></div><h2>{props.item.title}</h2><p><span className="bold">From ${props.item.price}</span> / person</p></div>)
}
对应的index.css中的内容。
.card {width: 175px;font-size: 0.75rem;flex: 0 0 auto;display: flex;flex-direction: column;position: relative
}.card--image {width: 100%;border-radius: 9px;margin-bottom: 9px;
}.card--title {overflow: hidden;text-overflow: ellipsis;
}.card--stats {display: flex;align-items: center;
}.card--star {height: 14px;
}.card--price {margin-top: auto;
}.card--badge{position: absolute;top: 6px;left: 6px;background-color: white;padding: 5px 7px;border-radius: 2px;font-weight: bold;
}h2 {font-size: 0.75rem;font-weight: normal;
}.gray {color: #918E9B;
}.bold {font-weight: bold;
}
7. 删除App.css中的所有内容
8. 准备需要的数据
在src文件夹之下建立data.jsx文件,准备在活动栏中需要呈现的内容。
data.jsx
export default [{id: 1,title: "Life Lessons with Katie Zaferes",description: "I will share with you what I call \"Positively Impactful Moments of Disappointment.\" Throughout my career, many of my highest moments only came after setbacks and losses. But learning from those difficult moments is what gave me the ability to rise above them and reach my goals.",price: 136,coverImg: "katie-zaferes.png",stats: {rating: 5.0,reviewCount: 6},location: "Online",openSpots: 0,},{id: 2,title: "Learn Wedding Photography",description: "Interested in becoming a wedding photographer? For beginner and experienced photographers alike, join us in learning techniques required to leave the happy couple with memories that'll last a lifetime.",price: 125,coverImg: "wedding-photography.png",stats: {rating: 5.0,reviewCount: 30},location: "Online",openSpots: 27,},{id: 3,title: "Group Mountain Biking",description: "Experience the beautiful Norwegian landscape and meet new friends all while conquering rugged terrain on your mountain bike. (Bike provided!)",price: 50,coverImg: "mountain-bike.png",stats: {rating: 4.8,reviewCount: 2},location: "Norway",openSpots: 3,}
]
9. 更新App.jsx中的内容
App.jsx
import Navbar from "../public/components/Navbar"
import Hero from "../public/components/Hero"
import Card from "../public/components/Card"
import data from "./data"export default function App() {const cards = data.map(item => {return (<Cardkey = {item.id}item = {item}/>)})return (<div><Navbar /><Hero /><section className="cards--list">{cards}</section></div>)
}
对应的index.css中的内容。
.cards--list {display: flex;flex-wrap: nowrap;gap: 20px;overflow-x: auto;
}
10. 完整的index.css
* {box-sizing: border-box;
}body {margin: 0;font-family: 'Poppins', sans-serif;
}nav {height: 70px;display: flex;padding: 20px 36px;box-shadow: 0px 2.98256px 7.4564px rgba(0, 0, 0, 0.1);
}h2 {font-size: 0.75rem;font-weight: normal;
}.gray {color: #918E9B;
}.bold {font-weight: bold;
}.nav--logo {max-width: 100px;
}section {padding: 20px;
}.hero {display: flex;flex-direction: column;
}.hero--photo {max-width: 400px;align-self: center;
}.hero--header {margin-bottom: 16px;
}.hero--text {margin-top: 0;
}.cards--list {display: flex;flex-wrap: nowrap;gap: 20px;overflow-x: auto;
}.card {width: 175px;font-size: 0.75rem;flex: 0 0 auto;display: flex;flex-direction: column;position: relative
}.card--image {width: 100%;border-radius: 9px;margin-bottom: 9px;
}.card--title {overflow: hidden;text-overflow: ellipsis;
}.card--stats {display: flex;align-items: center;
}.card--star {height: 14px;
}.card--price {margin-top: auto;
}.card--badge{position: absolute;top: 6px;left: 6px;background-color: white;padding: 5px 7px;border-radius: 2px;font-weight: bold;
}
11. 上传到github
12. 上传到netlify
相关文章:
使用React和Vite构建一个AirBnb Experiences克隆网站
这一篇文章中,我会教你如何做一个AirBnb Experiences的克隆网站。主要涵盖React中Props的使用。 克隆网站最终呈现的效果: 1. 使用vite构建基础框架 npm create vitelatestcd airbnb-project npm install npm run dev2. 构建网站的3个部分 网站从上…...
HBase压测 ycsb
## ycsb 导入数据 rootXX.14.40.1971、对portrait压测 ansible hadoop -i hosts_hbase_portrait_20230730.txt -m shell -a "hostname && chdir/data/workspace/ycsb-0.17.0 nohup bin/ycsb load hbase20 -P workloads/workload_insert -cp /usr/local/fqlhadoop/…...
基于Python+Django+Vue3+MySQL实现的前后端分类的商场车辆管理系统
项目名称:基于PythonDjangoVue3MySQL实现的前后端分离商场车辆管理系统 技术栈 开发工具:PyCharm、Visual Studio Code (VSCode)运行环境:Python 3.10、MySQL 8.0、Node.js 18技术框架:Django 5、Vue 3.4、Ant-Design-Vue 4.12 …...
网络安全web基础_HTML基础(扫盲篇)
web基础_HTML扫盲篇 一、什么是 HTML? 二、HTML 的基本特点 三、HTML 基本结构概述 1.文档声明(!DOCTYPE html) 2. html元素 3. head元素 4. body 元素 四、HTML5的主要标签清单 文档结构标签 文本内容标签 链接和锚点标签 表格标…...
(附项目源码)Java开发语言,监督管家APP的设计与实现 58,计算机毕设程序开发+文案(LW+PPT)
摘要 随着互联网的快速发展和智能手机的普及,越来越多的用户选择通过移动应用程序进行事项设定、提醒通知和事项打卡。监督管家APP作为一个专注于事项设定、提醒通知、事项打卡的监督管理平台,具有广泛的应用前景和商业价值。本研究旨在构建一个功能丰富…...
前端基础的讲解-JS(11)
对象 对象是什么? 在 JavaScript 中,对象是一组无序的相关属性和方法的集合,所有的事物都是对象,所有的数据类型都可以存放在内。 属性:即事物的特征,在对象中用属性来表示(常用名词…...
Python魔法方法深度解析:解密__call__、__new__和__del__的核心奥义
解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! Python中的魔法方法(Magic Methods)是构建Python高级功能的基础,它们使得对象可以…...
当微软windows的记事本被AI加持
1985年,微软发布了Windows 1.0,推出了一款革命性的产品:记事本(Notepad)。这款软件旨在鼓励使用一种未来主义的新设备——鼠标,并让人们可以不依赖VI等键盘工具就能书写文本和编写代码。记事本因其简洁和高…...
Python酷库之旅-第三方库Pandas(213)
目录 一、用法精讲 996、pandas.DatetimeIndex.day属性 996-1、语法 996-2、参数 996-3、功能 996-4、返回值 996-5、说明 996-6、用法 996-6-1、数据准备 996-6-2、代码示例 996-6-3、结果输出 997、pandas.DatetimeIndex.hour属性 997-1、语法 997-2、参数 99…...
普林斯顿:LLM基于边际优化的梯度纠缠
📖标题:A Common Pitfall of Margin-based Language Model Alignment: Gradient Entanglement 🌐来源:arXiv, 2410.13828 🌟摘要 🔸从人类反馈中强化学习(RLHF)已成为对齐语言模型…...
通俗易懂:什么是 Java 类加载?
文章目录 类加载过程的三个阶段一个简单的案例:类加载的工作原理使用这个类类加载的顺序类加载的特点类加载的好处总结推荐阅读文章 在 Java 中, 类加载是一种将我们写的 Java 类文件加载到内存中的过程,让 JVM(Java 虚拟机&…...
Dijkstra 算法的实现方案
下面是一个基于 Dijkstra 算法的实现方案,能够在 DEM(数字高程模型)数据上进行寻路,并满足以下需求: 使用 Qt C++ 编写; 规避 DEM 中的障碍物; 支持指定起点和终点; 使用 GDAL 库读取 DEM 文件; 输出路径到 TXT 文件; 输出的坐标为地理坐标(例如经纬度),而不是像…...
OpenGL 进阶系列07 - 阴影贴图(shadowmap )
一:概述: 在 OpenGL 中,Shadow Mapping(阴影贴图)是一种常用的实时阴影技术,用于渲染物体的阴影效果。这种方法通过生成光源视角下的深度贴图,再在场景渲染时使用它来判断物体是否被遮挡,从而实现阴影效果。下面是实现 Shadow Mapping 的基本步骤和相关知识。 二:绘制…...
【CAN介绍】【第一篇章】
1. CAN简介 • CAN 总线( Controller Area Network Bus )控制器局域网总线 • CAN 总线是由 BOSCH 公司开发的一种简洁易用、传输速度快、易扩展、可靠性高的串行通信总线,广泛应用于汽车、嵌入式、工业控制等领域 • CAN 总线特征࿱…...
【统计子矩阵——部分前缀和+双指针】
题目 代码 #include <bits/stdc.h> using namespace std; typedef long long ll; const int N 510; int s[N][N]; int main() {ios::sync_with_stdio(0);cin.tie(0);int n, m, k;cin >> n >> m >> k;for(int i 1; i < n; i)for(int j 1; j <…...
用正则表达式检查是IP否为内网地址
用正则表达式检查是ip否为内网地址 PHP function isIntranet($ip) {/* IPV4内网地址A 类10.0.0.0~10.255.255.255B 类172.16.0.0~172.31.255.255C 类192.168.0.0~192.168.255.255*/// 检查是否为 IPv4 内网地址if (preg_match(/^10\./, $ip…...
Leetcode刷题笔记14
136. 只出现一次的数字 136. 只出现一次的数字 - 力扣(LeetCode) 核心思想:按位异或运算 利用按位异或运算的性质来解决这个问题: 异或运算的性质: a ^ a 0:相同的数异或结果为0。 a ^ 0 a:…...
PHP图书绘本借阅管理系统小程序源码
📚 图书绘本借阅管理系统:打造孩子的阅读乐园 📚 🏷️ 引言:为什么我们需要图书绘本借阅管理系统? 在孩子的成长旅程中,阅读是不可或缺的一部分。然而,面对琳琅满目的图书和绘本&a…...
【JavaWeb】JavaWeb入门之XML详解
目录 1.XML介绍 1.1.XML概述 1.1.1.什么是XML 1.1.2.XML的作用 1.1.3.XML与HTML的比较 1.1.4.XML和properties(属性文件)比较 1.1.5.W3C组织 1.2.XML语法概述 1.2.1.XML文档展示 1.2.2.XML文档的组成部分 1.3.XML文档声明 1.3.1.什么是XML文…...
JS手写-this绑定实现
在 JavaScript 中,bind、call 和 apply 方法都可以用来改变函数的 this 指向。下面我们将分别实现这些方法的简单版本。 1. 实现 bind bind 方法创建一个新的函数,在调用时设置 this 值,并返回这个新的函数。 Function.prototype.myBind …...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...
GruntJS-前端自动化任务运行器从入门到实战
Grunt 完全指南:从入门到实战 一、Grunt 是什么? Grunt是一个基于 Node.js 的前端自动化任务运行器,主要用于自动化执行项目开发中重复性高的任务,例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...
