React + antd + ts 商城demo

目的:实现一个react的商城demo,实现含有购物车,登录,注册,商城等功能
源码地址:
使用到的技术栈:

  • 脚本:TypeScript
  • 前端框架:React
  • 路由管理:React-router-dom
  • 用户界面:Antd
  • 全局状态管理:Redux
  • 异步状态更新:redux-saga
  • 路由状态同步:connected-react-router
  • 网络请求:Axios
  • 调试工具:redux-devtools-extension

服务端:

  • 脚本:Node.js
  • 数据库:Mongodb
  • 数据库可视化:Robo 3T

搭建开发环境 (服务端)

2.1 安装 mongodb 数据库 (Mac)
  1. 安装 homebrew

    Homebrew 是mac系统中的软件包管理器

    /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
    
  2. 添加 mongodb 仓库源

    brew tap mongodb/brew
    
  3. 安装 mongodb

    安装前确保系统已经安装 xcode 命令行编译开发工具

    xcode-select --install 
    
    brew install mongodb-community
    
  4. 启动 mongodb

    brew services run mongodb-community
    
  5. 停止 mongodb

    brew services stop mongodb-community
    
  6. 文件位置

    1. 数据库配置文件:/usr/local/etc/mongod.conf
    2. 数据库文件默认存放位置:/usr/local/var/mongodb
    3. 日志存放位置:/usr/local/var/log/mongodb/mongo.log
2.2 安装 mongodb 数据库 (Windows)

请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述
请添加图片描述

2.3 数据库可视化 Robo 3T

下载地址

2.4 启动服务器端应用程序
  1. Mac 用户将服务器端应用程序文件夹拖拽到终端中,windows 用户打开服务器端应用程序文件夹,按住 shift 同时单击鼠标右键,选择在此处打开命令行工具 (cmd 或者 powershell)
  2. 执行 npm install 命令安装程序依赖文件
  3. 执行 npm start 命令启动服务器端应用程序,服务器端应用程序默认监听 80 端口

3. 搭建开发环境 (客户端)

3.1 创建项目并安装依赖
  1. 使用 create-react-app 脚手架创建 react 项目

    npx create-react-app ecommerce-front --template typescript

  2. 安装项目依赖

    npm install antd axios moment redux react-redux react-router-dom redux-saga connected-react-router redux-devtools-extension @types/react-redux @types/react-router-dom

  3. antd CSS 使用 CDN

    https://cdn.bootcdn.net/ajax/libs/antd/4.8.3/antd.min.css

3.2 配置服务器端 API 请求地址

在项目的根目录下新建 .env 文件,并在文件中添加以下内容:

REACT_APP_PRODUCTION_API_URL=http://fullstack.net.cn/api
REACT_APP_DEVLOPMENT_API_URL=http://localhost/api

create-react-app 脚手架中内置了 dotenv,允许我们在 React 项目中配置环境变量,但环境变量的名字必须以 REACT_APP_ 开头。

REACT_APP_PRODUCTION_API_URL: 生产环境的服务器端 API 地址

REACT_APP_DEVLOPMENT_API_URL:开发环境的服务器端 API 地址

在项目中可以通过 process.env.REACT_APP_DEVLOPMENT_API_URL 方式进行访问,但是这样会有弊端,其一是代码过长写起来不方便,其二是如果在代码中将环境写死,当切换环境时改起来也不方便。

解决方案就是将 API 地址写入配置中,根据环境决定使用哪个 API 地址

export let API: string

if (process.env.NODE_ENV === "development") {
   
  API = process.env.REACT_APP_DEVLOPMENT_API_URL!
} else {
   
  API = process.env.REACT_APP_PRODUCTION_API_URL!
}
3.3 安装 chrome 扩展

在这里插入图片描述

React Developer Tools:检查React组件层次结构,在页面上显示React组件。

在这里插入图片描述

Redux DevTools:监测 Store 中状态的变化
在这里插入图片描述

import { composeWithDevTools } from "redux-devtools-extension"

export const store = createStore(
  rootReducer,
  composeWithDevTools(applyMiddleware(...middlewares))
)

进行页面和路由初始化

src下新建component放置组件,新建admin,core放置公共代码,header,layout,shop部分

Layout.tsx

import {
    PageHeader } from "antd"
import React, {
    FC } from "react"
import Navigation from "./Navigation"

interface Props {
   
  children: React.ReactNode
  title: string
  subTitle: string
}

const Layout: FC<Props> = ({
    children, title, subTitle }) => {
   
  return (
    <div>
      <Navigation />
      <PageHeader className="jumbotron" title={
   title} subTitle={
   subTitle} />
      <div style={
   {
    width: "85%", margin: "0 auto" }}>{
   children}</div>
    </div>
  )
}

export default Layout

Routes.tsx

import React from "react"
import {
    HashRouter, Route, Switch } from "react-router-dom"
import Home from "./components/core/Home"
import Shop from "./components/core/Shop"
import Signin from "./components/core/Signin"
import Signup from "./components/core/Signup"
import Dashboard from "./components/admin/Dashboard"
import PrivateRoute from "./components/admin/PrivateRoute"
import AdminDashboard from "./components/admin/AdminDashboard"
import AdminRoute from "./components/admin/AdminRoute"
import AddCategory from "./components/admin/AddCategory"
import AddProduct from "./components/admin/AddProduct"
import Product from "./components/core/Product"
import Cart from "./components/core/Cart"
import Success from "./components/core/Success"
import Orders from "./components/admin/Orders"

const Routes = () => {
   
  return (
    <HashRouter>
      <Switch>
        <Route path="/" component={
   Home} exact />
        <Route path="/shop" component={
   Shop} />
        <Route path="/signin" component={
   Signin} />
        <Route path="/signup" component={
   Signup} />
        <Route path="/cart" component={
   Cart} />
        <Route path="/paysuccess" component={
   Success} />
        <PrivateRoute path="/user/dashboard" component={
   Dashboard} />
        <AdminRoute path="/admin/dashboard" component={
   AdminDashboard} />
        <AdminRoute path="/create/category" component={
   AddCategory} />
        <AdminRoute path="/create/product" component={
   AddProduct} />
        <AdminRoute path="/admin/orders" component={
   Orders} />
        <Route path="/product/:productId" component={
   Product} />
      </Switch>
    </HashRouter>
  )
}

export default Routes

创建store文件夹放置reducers和actions,saga等

sotre/index.ts

import {
    applyMiddleware, createStore } from "redux"
import createRootReducer from "./reducers/index"
import {
    createHashHistory } from "history"
import {
    routerMiddleware } from "connected-react-router"
import createSagaMiddleware from "redux-saga"
import rootSaga from "./sagas/index"
import {
    composeWithDevTools } from "redux-devtools-extension"

export const history = createHashHistory()

const sagaMiddleware = createSagaMiddleware()

const store = createStore(
  createRootReducer(history),
  composeWithDevTools(
    applyMiddleware(routerMiddleware(history), sagaMiddleware)
  )
)

sagaMiddleware.run(rootSaga)

export default store

使用connected-react-router监听路由的变化

store/reducers/index.ts

import {
    applyMiddleware, createStore } from "redux"
import createRootReducer from "./reducers/index"
import {
    createHashHistory } from "history"
import {
    routerMiddleware } from "connected-react-router"
import createSagaMiddleware from "redux-saga"
import rootSaga from "./sagas/index"
import {
    composeWithDevTools } from "redux-devtools-extension"

export const history = createHashHistory()

const sagaMiddleware = createSagaMiddleware()

const store = createStore(
  createRootReducer(history),
  composeWithDevTools(
    applyMiddleware(routerMiddleware(history), sagaMiddleware)
  )
)

sagaMiddleware.run(rootSaga)

export default store

登录注册及首页

在antd中使用导航组件,menu菜单,在Layout中引用

Navigation.tsx

import {
    Badge, Menu } from "antd"
import React, {
    useContext, useEffect } from "react"
import {
    useSelector } from "react-redux"
import {
    Link } from "react-router-dom"
import {
    AppState } from "../../store/reducers/index"
import {
    RouterState } from "connected-react-router"
import {
    isAuth } from "../../helpers/auth"
import {
    Jwt } from "../../store/models/auth"
import {
    TotalContext } from "../../anotherStore"
import {
    itemCount } from "../../helpers/cart"

function useActive(currentPath: string, path: string): string {
   
  return currentPath === path ? "ant-menu-item-selected" : ""
}

const Navigation = () => {
   
  const router = useSelector<AppState, RouterState>(state => state.router)
  const pathname = router.location.pathname
  const isHome = useActive(pathname, "/")
  const isShop = 
  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值