在 create-react-app 中使用 Ant Design Landing 模板:完整集成与多页面路由实战指南

原创2026-10-05 22:37:171,815 阅读
文章标签:前端文档

在 create-react-app 中使用 Ant Design Landing 模板:完整集成与多页面路由实战指南

导读

create-react-app 是业界最优秀的 React 应用开发工具之一。本文以 Ant Design Landing 项目中下载的 Home 模板包为核心,系统讲解如何在 create-react-app 创建的工程中完成目录合并、Less 加载配置、入口文件替换,并进一步实现基于 react-router-dom 的多页面导航。阅读完本文后,你将掌握一套可直接复制运行的集成方案,能够在自己的 CRA 项目中快速落地 Ant Design Landing 的落地页模板。

安装与初始化

create-react-app 的安装与初始化流程可参考其官方文档,或查阅 antd 官方的 use-with-create-react-app 章节。安装完成后,默认工程目录结构如下:

├── README.md
├── node_modules
├── package.json
├── .gitignore
├── public
│   ├── favicon.ico
│   ├── index.html
│   └── manifest.json
│── src
│   ├── App.css
│   ├── App.js
│   ├── App.test.js
│   ├── index.css
│   ├── index.js
│   ├── logo.svg
│   └── serviceWorker.js

Ant Design Landing 是一个基于 Ant Design 体系的落地页模板与在线编辑器项目(仓库即 ant-design-landing),其下载的模板包以 Home 为根目录,内部同时包含 .jsx 组件文件与 .less 样式文件。关于模板包的标准目录结构与数据文件约定,可进一步参考 开始使用文档:

│── less
│   ├── index.less
│   ├── common.less            # 通用样式
│   ├── content.less           # 内容模块通用样式
│   ├── custom.less            # less 变量文件
│   ├── edit.less              # 编辑器里编辑后生成的样式
│   ├── Banner0.less *         # 相关模块样式
│   ├── Content0.less *
│     ...
│── data.source.js             # 内容数据文件
│── index.js                   # 主入口
│── Banner0.jsx *              # 相关模块
│── Content0.jsx *
│   ...

以上加 * 号为可配置内容,当你在编辑器里选择了哪些模块,将对应出现相应的文件。

合并目录:将 Home 模板包拷贝进 src

直接从 Landing 上下载 Home 文件夹,拷贝到新建工程的 src 目录下:

├── README.md
├── ...
├── public
│   ├── ...
│── src
+   ├── Home
+   │    ├── less
+   │    ├── index.js
+   │    ├── ...
│   ├── App.css
│   ├── App.js
│   ├── App.test.js
│   ├── index.css
│   ├── index.js
│   ├── logo.svg
│   └── serviceWorker.js

从源码结构看,模板包中的 data.source.js 是内容数据文件,所有可编辑文案、图片地址与菜单配置都集中于此;组件内部通过 { ...Banner00DataSource.title } 之类的展开语法复用这些数据并以 props 传入。以仓库中的 Nav0 模板配置 为例,其 dataSource 中定义了 wrapper、page、logo、Menu、mobileMenu 等节点,Menu.children 数组中的每一项对应一个导航项,包含 name、className、children.href、children.children(文本内容)等字段。这正是后续路由改造时修改 data.source.js 中 href 值的依据所在。

安装依赖

详细依赖清单请参考 开始使用文档中的安装依赖章节。Ant Design Landing 依赖 ant design 的相关组件,动效依赖 ant motion 中的动效组件,基本必要依赖如下:

npm install antd enquire-js rc-queue-anim rc-scroll-anim rc-tween-one --save;
npm install rc-banner-anim --save;// 如果用的是多屏滑动型的 banner,加上这条;
npm install @ant-design/compatible --save;// 如果使用了 Content7 模块,请加上这条;

关于按需加载:umi 或 ant design pro 无需安装此项,CRA 场景下如使用 babel-plugin-import 需要安装 npm install babel-plugin-import --save-dev,且需注意:目前加载的是全部 ant design 的 less,若使用了 babel-plugin-import,请将 less/custom.less 里的 @import "~antd/lib/style/index.less"; 更换成 @import "~antd/lib/style/themes/default.less";。

另外,为确保移动端响应式布局效果,需要在 html 文件的 head 里配置:

<meta name="viewport" content="width=device-width, initial-scale=1.0">

less 加载支持

CRA 默认不支持 Less 预处理,需要安装以下工具链:

npm install react-app-rewired customize-cra less less-loader
  • react-app-rewired:在不执行 eject 的前提下覆写 CRA 的 webpack 配置;
  • customize-cra:提供 override、fixBabelImports、addLessLoader 等便捷组合函数;
  • less / less-loader:Less 编译工具链。

配置加载 less

安装完 less 加载相关依赖后,需要修改 package.json 中的启动配置,将 scripts 指向 react-app-rewired:

/* package.json */
"scripts": {
-   "start": "react-scripts start",
+   "start": "react-app-rewired start",
-   "build": "react-scripts build",
+   "build": "react-app-rewired build",
-   "test": "react-scripts test",
+   "test": "react-app-rewired test",
}

创建 config-overrides.js

在项目根目录创建一个 config-overrides.js 用于修改默认配置:

├── README.md
├── node_modules
├── package.json
├── .gitignore
+── config-overrides.js
├── public
│   ├── ...
│── src
│   ├── Home
│   └── ...

config-overrides.js 详解

const { override, fixBabelImports, addLessLoader } = require('customize-cra');

module.exports = override(
  // 按需加载 antd
  fixBabelImports('import', {
    libraryName: 'antd',
    libraryDirectory: 'es',
    style: true,
  }),
  // 添加加载 less 的 javascriptEnabled 和 antd 的主题配置。
  addLessLoader({
    lessOptions: {
      javascriptEnabled: true,
      modifyVars: { '@primary-color': '#1DA57A' },
    }
  }),
);

关键配置项说明:

配置项 作用 说明
fixBabelImports('import', {...}) antd 按需加载 libraryName: 'antd' 指定组件库名,libraryDirectory: 'es' 指向 ES 模块目录,style: true 自动引入组件对应样式
addLessLoader({...}) 注册 Less loader 使工程中的 .less 文件能被 webpack 编译
javascriptEnabled: true 允许 Less 中执行 JS 表达式 Ant Design 的 Less 主题变量依赖该特性,关闭会导致编译失败
modifyVars Less 变量覆盖 用于自定义 antd 主题,示例将主色 @primary-color 改为绿色 #1DA57A

本文只引用 antd 的高级配置,eject 同样不在本文讨论范围,eject 可参考 yarn run eject(对应 create-react-app 官方文档的 "Converting to a custom setup" 章节)。值得注意的是,Ant Design Landing 默认使用 Less 作为样式语言,且整个文件的 Less 未使用 css-modules,需直接使用;如果你的脚手架启用了 css-modules,请在 index.less 里用 :global 包裹 import 语句(详见 开始使用文档的样式章节)。

修改入口文件

打开 src/index.js,将默认的 App 组件替换为从 Landing 下载的 Home 组件并渲染:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
- import App from './App';
+ import App from './Home';
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<App />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: http://bit.ly/CRA-PWA
serviceWorker.unregister();

从模板包源码看,Home/index.js 是模板的主入口,内部负责汇总各模块组件(如 Banner0、Content0、Nav0、Footer0)并注入各自的 dataSource 数据。因此将 index.js 的默认导出指向 ./Home 后,整个落地页即可直接渲染。

完成单页集成

完成以上步骤之后,运行 npm start 即可在浏览器中查看从 Landing 下载的模板效果。


额外内容:多页面路由

如果只是单个落地页,以下内容可以略过。当需要将落地页整合进一个多页面站点时,需要引入路由。

安装 react-router-dom

create-react-app 本身不提供路由配置,因此需要安装 react-router-dom:

npm install react-router-dom --save

配置路由

将上述修改入口文件的改动恢复为原始状态(import App from './App'),然后对 App.js 进行改造:添加 Router 入口,并提取 Header(Nav0)与 Footer(Footer0)作为全局布局组件。

App.js
import React, { Component } from 'react';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import { enquireScreen } from 'enquire-js';
import Header from './Home/Nav0';
import Footer from './Home/Footer0';
import Home from './Home';

import {
  Nav00DataSource,
  Footer00DataSource,
} from './Home/data.source.js';

let isMobile;
enquireScreen((b) => {
  isMobile = b;
});

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      isMobile,
    };
  }
  componentDidMount() {
    // 适配手机屏幕;
    enquireScreen((b) => {
      this.setState({ isMobile: !!b });
    });
  }
  render() {
    return (
      <Router>
        <div>
          <Header dataSource={Nav00DataSource} isMobile={this.isMobile} />
          <Route exact path="/" component={Home} />
          <Footer dataSource={Footer00DataSource} isMobile={this.isMobile} />
        </div>
      </Router>
    );
  }
}

export default App;

代码要点解析:

  • enquireScreen 来自 enquire-js(已在依赖安装步骤中引入),用于检测当前是否为移动端屏幕,并驱动模板组件的响应式切换;
  • Nav00DataSource 与 Footer00DataSource 从 ./Home/data.source.js 导出,命名遵循「模块名 + 序列号 + DataSource」的约定(详见 开始使用文档的数据文件章节);
  • 从源码看,Nav0 组件 接收 dataSource 与 isMobile 两个核心 props:dataSource 控制导航内容与动效参数,isMobile 决定菜单以 inline 模式还是 horizontal 模式渲染;Footer0 组件 同样通过 dataSource 驱动版权信息与滚动动效。这正是为什么在路由方案中要将两者提升为全局布局的原因。

注:如果觉得 enquireScreen 多次出现比较不舒服,可以选择用 React Context 或其它方式传递移动端状态,详见 React Context 官方文档。

添加页面

从 Landing 上下载另一个模板页面,将其重命名(如 Page2),避免与已有的 Home 目录冲突;拷贝到 src 目录下。注意:新页面中不需要 Nav 和 Footer 组件,可将其移除。然后在 App.js 中为该新页面添加路由入口:

App.js
import React, { Component } from 'react';
...
import Home from './Home';
+ import Page2 from './Page2';

....

class App extends Component {
  ...
  render() {
    return (
      <Router>
        <div>
          <Header dataSource={Nav00DataSource} isMobile={this.isMobile} />
          <Route exact path="/" component={Home} />
+         <Route exact path="/page2" component={Page2} />
          <Footer dataSource={Footer00DataSource} isMobile={this.isMobile} />
        </div>
      </Router>
    );
  }
}

export default App;

修改 Nav0 相关参数

要让导航菜单支持多页面跳转,需要把菜单项从普通 <a> 标签改为 react-router 的 <Link> 组件。先修改 Home 里的 Nav0 文件。

也可以将 Nav0 和 Footer0 提出放到一个文件包里,如 Layout,便于统一管理全局布局。

./src/Home/Nav0
import React from 'react';
...
import { Menu } from 'antd';
+import { Link } from "react-router-dom";

const Item = Menu.Item;

class Header extends React.Component {
  ....
    const navChildren = Object.keys(navData).map((key, i) => (
      <Item key={i.toString()} {...navData[key]}>
-       <a
+       <Link
          {...navData[key].a}
+         href={navData[key].a.href}
+         to={navData[key].a.href}
          target={navData[key].a.target}
        >
          {navData[key].a.children}
-       </a>
+       </Link>
      </Item>
  ...
}

export default Header;

对照仓库中 Nav0 的原始实现,可以看到其 render 方法中正是通过 navData.map(...) 遍历 dataSource.Menu.children 生成 Menu.Item,并以 <a {...a}> 渲染菜单链接(其中 a 即 item.children 中的链接配置对象)。此处的路由改造即是将 <a> 替换为 <Link>,同时保留 to 与 href 属性以兼容 data.source.js 中的数据字段。

接下来修改 data.source.js 中的 href 值,让导航指向对应路由:

export const Nav00DataSource = {
  ...
  Menu: {
    className: 'header0-menu',
    children: [
-     { name: 'item0', a: { children: '导航一', href: '' } },
+     { name: 'item0', a: { children: '导航一', href: '/' } },
-     { name: 'item1', a: { children: '导航二', href: '' } },
+     { name: 'item1', a: { children: '导航二', href: '/page2' } },
      { name: 'item2', a: { children: '导航三', href: '' } },
      { name: 'item3', a: { children: '导航四', href: '' } },
    ],
  },
  ...
};

该数据结构与仓库中 Nav0 模板配置 的 Menu.children 定义完全对应:每个导航项包含 name、className、children.href(链接地址)与 children.children(导航文本,数组形式),子菜单通过 subItem 字段描述。

路由配置完成

完成以上步骤之后,再次运行 npm start,即可在浏览器中看到落地页,并可通过顶部导航在多个页面之间切换。至此,Ant Design Landing 模板在 create-react-app 中的单页落地与多页路由两种集成方式均已配置完成。

登录后查看全文
ant-design-landing