使用 React 和 8base 构建电子商务网站
作者:Ogundipe Samuel✏️
2018年,在线购物市场的总价值估计约为2.84万亿美元。亚马逊、沃尔玛和阿里巴巴等公司位居榜首。这些巨头凭借其庞大的平台,为小型企业运营和拥有自己的电商商店打开了新的窗口。
在本教程中,我们将使用 React 作为前端并使用 8base 作为后端构建一个电子商务网站。
注意:要学习本教程,您需要对 React 和 Node.js 有基本的了解。请确保在开始之前已安装 Node 和 npm/yarn。我们还将在项目中使用一些 GraphQL 查询,因此熟悉 GraphQL 会很有帮助。
什么是 React?
React是一个基于组件的 JavaScript 库,用于构建用户界面。它允许我们构建封装的组件来管理其状态,然后将它们组合起来以创建复杂的 UI。
什么是 8base?
8base 是一个 GraphQL 后端,允许 JavaScript 开发者使用全栈 JavaScript 快速交付企业应用程序。它与前端框架无关,因此开发者可以随心所欲地创建面向客户的应用程序。
我们将使用 8base 作为我们应用的后端数据库层。我们将在这里存储我们电商网站的产品信息。
入门
8base 提供丰富的功能,帮助开发人员更快、更轻松地构建高性能应用程序。使用 8base 控制台,您可以通过简单的 GUI 构建后端,该控制台允许您执行以下操作:
- 定义数据模式:创建表/表关系
- 设置权限和授权角色
- 将多个项目组织到工作区中
- 使用 API 浏览器设计查询(基于 GraphQL)
- 管理文件
要开始使用 8base,请按照以下步骤操作:
- 在8base上创建一个帐户。您可以开始免费使用 8base。
- 注册完成后,单击数据生成器按钮导航到数据菜单,然后单击“新建表”开始构建后端。
- 新表加载完成后,您将进入模式界面,开始定义字段。我们来看一下,并注意以下几点。在左侧,您会看到
System Tables
和Your Tables
。
每个新的 8base 工作区都自动预装了一些内置表。这些表用于处理文件、设置和权限等内容,并且可以通过 8base GraphQL API 访问。
- 继续创建一个表,
Products, which will consist of the following fields:
名称:“”
类型:字段类型为文本。
描述:“这将是产品的名称”
价格:“”
类型:字段类型为数字。
描述:“此字段将保存我们产品的价格。”
描述:“”
类型:字段类型为文本。
描述:“此字段将保存我们产品的描述。”
图像:“”
类型:字段类型为文件。
描述:“此字段将保存我们产品的图像。”
- 我们需要一些示例帖子,所以让我们添加一些示例数据。在我们创建架构的架构菜单图标旁边,点击“数据”选项卡,然后通过设置标题和正文来添加示例产品记录。
- 接下来,复制 API 端点 URL(位于左下角)——这是您的前端和 8base 后端之间通信的单一端点。
- 最后,在本教程中,我们将默认允许访客访问,因此身份验证是可选的。要允许访客访问新的“产品”表,请导航到
Settings > Roles > Guest,
“产品和文件”下并选中相应的复选框。
访问您的 API 端点的所有未经身份验证的用户默认都被分配有访客角色。
本教程不涉及身份验证。您可以点击此处详细了解如何处理身份验证。
只需几个简单的步骤,我们就使用 8base 搭建好了可用于生产的 CMS 后端。现在,让我们开始构建应用程序的前端。
使用 React
要开始使用 React,我们必须先安装它。最快的启动和运行方式是使用CRA。
如果您尚未在开发机器上安装它,请打开终端并运行以下命令:
npx create-react-app
生成 React 项目
安装成功后,你就可以启动一个新的 React 项目了。要创建我们的项目,请运行以下命令:
npx create-react-app shopping-cart
npm start
通过在项目根文件夹中的终端中运行来启动 React 应用服务器。
创建我们的布局
让我们开始创建项目的布局。我们的应用将包含 5 个不同的组件。
- 导航栏:用于保存导航和购物车图标
- 产品:显示产品列表。 –产品:单个产品的标记
- 页脚:我们的应用程序的页脚
- 购物车:用于存放购物车中的商品
我们将在项目中使用 Bootstrap,所以首先让我们引入它。打开index.html
公共文件夹,并在 head 部分添加以下链接标签:
// ./public/index.html
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
现在我们可以在我们的应用程序中使用引导类。
接下来,创建一个组件文件夹并在其中创建以下组件:Navbar.js、Products.js、Product.js、Footer.js、Cart.js。
打开 Navbar.js 并添加以下代码:
// src/components/Navbar.js
import React from 'react';
const Navbar = () => {
return (
<nav className="navbar navbar-light bg-light">
<a className="navbar-brand">Shoppr</a>
<button className="btn btn-outline-success my-2 my-sm-0" type="submit">Cart</button>
</nav>
);
};
export default Navbar;
打开 Footer.js 并添加以下代码:
// src/components/Footer.js
import React from 'react';
import '../App.css';
const Footer = () => {
return (
<footer className="page-footer font-small bg-blue pt-4">
<div className="container text-center text-md-left">
<div className="row">
<div className="col-md-6 mt-md-0 mt-3">
<h5 className="text-uppercase font-weight-bold">Contact Us</h5>
<p>You can contact us on 234-8111-111-11</p>
</div>
<div className="col-md-6 mb-md-0 mb-3">
<h5 className="text-uppercase font-weight-bold">Return Policy</h5>
<p>We accept returns after 7 days max</p>
</div>
</div>
</div>
<div className="footer-copyright text-center py-3">© 2019 Copyright:
<span> Shoppr</span>
</div>
</footer>
);
};
export default Footer;
我们的页脚需要一些样式,因此我们需要在文件中添加以下样式App.css
:
// src/App.css
footer {
position: absolute;
bottom: 0;
width: 100%;
background-color: #333;
color:#fff;
}
在创建产品组件之前,我们需要查询 8base,以便获取产品详细信息以供显示。现在就开始吧。
使用 GraphQL 连接到 8base 后端
要将我们的应用程序连接到后端,我们需要安装几个 GraphQL 包。我们使用的库之一是apollo-boost,它提供了一个客户端,可以通过 URI 连接到 GraphQL 后端。
该 URI 是 8base 提供的端点,可在仪表板的数据页面上找到。
在终端中运行以下命令来安装必要的软件包:
npm install apollo-boost graphql graphql-tag react-apollo
成功后,继续将index.js
src 目录中的文件更新为以下代码:
import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import { ApolloProvider } from "react-apollo";
import ApolloClient from "apollo-boost";
import * as serviceWorker from './serviceWorker';
const client = new ApolloClient({
uri: "<YOUR_8BASE_ENDPOINT>"
});
ReactDOM.render(
<ApolloProvider client={client}>
<App />
</ApolloProvider>,
document.getElementById('root')
);
serviceWorker.unregister();
我们用ApolloProvider
一个只接受一个 prop(即 client)的 ApolloProvider 包装了整个应用程序。ApolloProvider 加载了 8base 表结构,这使您可以访问应用程序内部数据模型的所有属性。
展示我们的产品
我们已经能够将 8base 中的表模式加载到我们的应用程序中。下一步是获取并显示我们的产品。
在组件文件夹下创建一个product-list
文件夹,然后创建一个index.js
文件并向其中添加以下内容:
// src/components/product-list/index.js
import gql from "graphql-tag";
import { graphql } from "react-apollo";
const PRODUCTS_QUERY = gql`
query {
productsList {
items {
id
createdAt
name
price
description
image {
downloadUrl
}
}
}
}
`;
export default PRODUCTS_QUERY;
这里,我们创建一个名为 的常量PRODUCTS_QUERY
来存储查询。该gql
函数用于解析包含 GraphQL 代码的纯字符串。
我们已经在后端填充了一些数据。为了测试我们的查询是否正常工作,8base 专门为此提供了一个便捷的 GraphQL 资源管理器。在 8base 仪表板的菜单中,点击 API 资源管理器图标并运行查询。
现在,我们确信查询可以正常工作了。让我们继续创建产品的组件。
打开您的Products.js
组件并向其中添加以下代码:
// src/components/Products.js
import React, { Component } from 'react';
import { Query } from 'react-apollo';
import PRODUCTS_QUERY from './product-list/index';
import Product from './Product';
import Navbar from './Navbar';
class Products extends Component {
constructor(props) {
super(props);
this.state = {
cartitems: []
};
}
addItem = (item) => {
this.setState({
cartitems : this.state.cartitems.concat([item])
});
}
render() {
return (
<Query query={PRODUCTS_QUERY}>
{({ loading, error, data }) => {
if (loading) return <div>Fetching</div>
if (error) return <div>Error</div>
const items = data.productsList.items;
return (
<div>
<Navbar/>
<div className="container mt-4">
<div className="row">
{items.map(item => <Product key={item.id} product={item} addItem={this.addItem} />)}
</div>
</div>
</div>
)
}}
</Query>
);
}
};
导出默认产品;在这里,我们用<Query/>
组件包装我们的产品并传递PRODUCTS_QUERY
as 属性。
Apollo 在组件的 中注入了几个 props render prop function
。这些 props 本身提供了有关网络请求状态的信息:
loading
:true
只要请求仍在进行中并且尚未收到响应,就会出现这种情况。error
:如果请求失败,此字段将包含有关具体出错原因的信息。data
:这是从服务器接收的实际数据。它具有items
表示元素列表的属性product
。
最后,我们循环遍历所有接收到的条目,并将它们作为 prop 传递给 Product 组件。在了解它是什么样子之前,我们先来创建一下Product
组件。
打开你的Product.js
并添加以下代码:
// src/components/Product.js
import React from 'react';
const Product = (props) => {
return (
<div className="col-sm-4">
<div className="card" style={{width: "18rem"}}>
<img src={props.product.image.downloadUrl} className="card-img-top" alt="shirt"/>
<div className="card-body">
<h5 className="card-title">{props.product.name}</h5>
<h6 className="card-title">$ {props.product.price}</h6>
<button className="btn btn-primary" onClick={() => props.addItem(props.product)}>Buy now</button>
</div>
</div>
</div>
);
}
export default Product;
我们的Product.js
是一个功能组件,它通过 props 接收产品详细信息并显示它们。
我们还在addItem
点击方法上调用函数,以便在点击当前产品时将其添加到购物车中。
现在,我们所有的组件都已设置好,我们需要将它们导入到App.js
我们的基础组件中。打开它并添加以下内容:
// src/App.js
import React from 'react';
import './App.css';
import Footer from './components/Footer';
import Products from './components/Products';
function App() {
return (
<div className="App">
<Products />
<Footer/>
</div>
);
}
export default App;
在浏览器中转到https://localhost:3000 ,您将看到以下内容:
此时,我们有一个展示产品的商店,我们需要添加将商品添加到购物车的功能。
添加购物车功能
要添加购物车功能,我们需要向组件添加更多方法。
更新您的products.js
内容如下:
// src/components/products.js
import React, { Component } from 'react';
import { Query } from 'react-apollo';
import PRODUCTS_QUERY from './product-list/index';
import Product from './Product';
import Cart from './Cart';
import Navbar from './Navbar';
class Products extends Component {
constructor(props) {
super(props);
this.state = {
cartitems: []
};
this.addItem = this.addItem.bind(this);
}
addItem(item){
this.setState({
cartitems : this.state.cartitems.concat([item])
});
}
showModal = () => {
this.setState({ show: true });
};
hideModal = () => {
this.setState({ show: false });
};
render() {
return (
<Query query={PRODUCTS_QUERY}>
{({ loading, error, data }) => {
if (loading) return <div>Fetching</div>
if (error) return <div>Error</div>
const items = data.productsList.items;
const itemssent = this.state.cartitems;
return (
<div>
<Navbar cart={itemssent} show={this.showModal} />
<Cart show={this.state.show} items={itemssent} handleClose={this.hideModal}>
</Cart>
<div className="container mt-4">
<div className="row">
{items.map(item => <Product key={item.id} product={item} addItem={this.addItem} />)}
</div>
</div>
</div>
)
}}
</Query>
)
};
};
export default Products;
Navbar.js
使用以下代码更新您的:
// src/components/Navbar.js
import React from 'react';
const Navbar = (props) => {
return (
<nav className="navbar navbar-light bg-light">
<h3>Shoppr</h3>
<button className="btn btn-outline-success my-2 my-sm-0" onClick={() => props.show()}>Cart {(props.cart.length)}</button>
</nav>
);
};
export default Navbar;
现在,创建一个Cart.js
文件并向其中添加以下代码:
import React from 'react';
const Cart = ({ handleClose, show, items }) => {
return (
<div className={show ? "modal display-block" : "modal display-none"}>
<section className="modal-main">
{items.map(item =>
<div className="card" style={{width: "18rem"}}>
<img src={item.image.downloadUrl} className="card-img-top" alt="shirt"/>
<div className="card-body">
<h5 className="card-title">{item.name}</h5>
<h6 className="card-title">$ {item.price}</h6>
</div>
</div>
)}
Total items: {items.length}
<button className="btn btn-warning ml-2" onClick={handleClose}>close</button>
</section>
</div>
);
};
export default Cart;
我们需要一些样式来正确显示购物车窗口。打开你的页面app.css
并添加以下代码:
.modal {
position: fixed;
top: 0;
left: 0;
width:100%;
height: 100%;
background: rgba(0, 0, 0, 0.6);
}
.modal-main {
position:fixed;
background: white;
width: 80%;
height: auto;
top:50%;
left:50%;
padding: 10px;
transform: translate(-50%,-50%);
}
.display-block {
display: block;
}
.display-none {
display: none;
}
现在打开您的购物车,添加商品并通过购物车按钮查看:
结论
在本教程中,我们创建了一个基本的电商商店。这里学到的概念可以帮助您创建强大的电商网站,而无需担心后端基础设施。您可以在这里了解更多关于 React 的信息,在这里了解更多关于 8base 的信息。您可以在这里找到本教程中使用的代码。
祝您编码愉快。
编者注:觉得这篇文章有什么问题?您可以在这里找到正确版本。
插件:LogRocket,一个用于 Web 应用的 DVR
LogRocket是一款前端日志工具,可让您重播问题,就像它们发生在您自己的浏览器中一样。无需猜测错误发生的原因,也无需要求用户提供屏幕截图和日志转储,LogRocket 让您重播会话,快速了解问题所在。它可与任何应用程序完美兼容,不受框架限制,并且提供插件来记录来自 Redux、Vuex 和 @ngrx/store 的额外上下文。
除了记录 Redux 操作和状态外,LogRocket 还记录控制台日志、JavaScript 错误、堆栈跟踪、带有标头 + 正文的网络请求/响应、浏览器元数据以及自定义日志。它还会对 DOM 进行插桩,以记录页面上的 HTML 和 CSS,即使是最复杂的单页应用程序,也能重现像素完美的视频。
免费试用。
使用 React 和 8base 构建电子商务网站一文首先出现在LogRocket 博客上。
鏂囩珷鏉ユ簮锛�https://dev.to/bnevilleoneill/building-an-e-commerce-website-with-react-and-8base-5mo